Path notecard maker

Creating scripts
Post Reply
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Path notecard maker

Post by Sherrie Melody »

I'm working on an animated duck, and I wanted an easy way to make complex paths for the duck (or ducks) to follow. I came up with this set of objects:
path-maker-image.png
Together, they let you create a "path" notecard that contains positions and rotations that can be used for animating an object, at least in my case. The format of each position/rotation line is:
DRIVE=[position]=[rotation]

You can change the format, this is just what i needed for my duck :D

Further down, I'm including the scripts, if you want to make your own. If not, you can pick up a package with these objects on Furthermore, http://www.kitely.com/virtual-world/She ... urthermore, (in the building near the landing point). It's a red box with "Path notecard maker" hover text.

To use them, you rez the path markers along the desired path, rotating each path marker in the direction your object should face at that position, for example:
example-path.png
Then rez the path recorder, touch the black child prim to make sure it has no previous positions recorded, then touch the green prim to get the recorder to start listening.

Then beginning with the first path marker, touch each path marker in the order that you want your object to follow.

After touching the last path marker in the path, touch the red child prim on the recorder to make it stop listening.

Lastly, touch the blue child prim to make the recorder create your "path" notecard. You will find the "path" notecard created inside the "path recorder" object.

MAKING YOUR OWN
To make the "path marker" object, rez a box, make sure it has ZERO rotation. Name it "path marker"
Face 3 (on the north side of the object) designates the "front" of the path marker. I used an arrow image on the top face pointing toward Face 3, but you could also just color Face 3 different so its easy to tell where it's pointing.

To make the "path recorder" 5-prim object, you will have a root prim of some sort, plus four child prims, named "start", "stop", "save", and "reset", as in my example:
path-recorder-parts-image.png
Link the child prims to the root prim (selecting the root prim last, then CTRL+L to link them). name the object something like "path recorder" ... or whatever you like.

Drop the following script in the "path marker" object:

Code: Select all

integer channel = -9992848845;//must be the same channel as the path recorder object script

//don't change below
vector position;
rotation rot;

default
{
    state_entry()
    {
        llOwnerSay("Touch when ready.");
    }
    touch_start(integer param) {
        position = llGetPos();
        rot = llGetRot();
        
        llRegionSay(channel, "DRIVE=" + (string)position + "=" + (string)rot);
        llOwnerSay("Position/rotation sent.");     
    }
}
Drop the following script in the root prim of your "path recorder" object:

Code: Select all

integer channel = -9992848845;//must be the same channel in the "path marker" prim script
                                //if you are using multiple path makers in a world, make sure each set has a different channel
                                
//don't change anything below
integer listen_handle;
list cardContents;
integer status=0;//0-not recording, 1-recording
key owner;
integer id;

string card = "paths";

default
{
    state_entry()
    {
        owner = llGetOwner();
        llOwnerSay("Touch GREEN prim to start (after path markers are positioned and properly rotated), RED to stop, BLUE to make notecard, BLACK to reset.\n\n");
    }
    touch_start(integer num_detected) {

        for(id=0;id<num_detected;id++){
            key who = llDetectedKey(id);
            string prim = llGetLinkName(llDetectedLinkNumber(id));
            if(who == owner) {
                if(prim == "start") {//owner touched "start" prim
                    listen_handle = llListen(channel, "path marker", "", "");//start a listen for "path marker" prims
                    llOwnerSay("I'm listening for the path markers. They will message me their position and rotation as you touch them. Touch them in the order that you want the object to move along the path.");

                }
                else if(prim == "stop") {//stop listening

                    llListenRemove(listen_handle);
                    llOwnerSay("I've stopped listening. If you touched at least 2 path markers, touch my blue prim to save the positions and rotations to a notecard. Or, to clear my memory touch the black prim.");

                }
                else if(prim == "save") {//make notecard of positions and rotations
                    llListenRemove(listen_handle);
                    integer listcount = llGetListLength(cardContents);
                    if(listcount < 2) {
                        llOwnerSay("I have " + (string)listcount + " positions recorded. That's not enough to make a paths card.");
                    }
                    else {
                        llOwnerSay("I have " + (string)listcount + " positions recorded.");
                        osMakeNotecard(card,cardContents);
                        llOwnerSay("I have made the card: " + card);
                    }


                }
                else if(prim == "reset") {//clear memory, remove notecard if exists
                    cardContents = [];//clears path list
                    llRemoveInventory(card);//removes the card, if its there
                    llOwnerSay("I have been reset, path positions cleared, paths notecard removed (if exists)");
                    llListenRemove(listen_handle);
                }

            }


        }
    }
    
     listen(integer channel, string name, key id, string message)
    {
        cardContents = cardContents + message;//add message string to cardContents list
        
    }
    
}
If you want to change the format of the line entries created in the "path" notecard, update the "path marker" script, llRegionSay line.

For example, if you just wanted the position and rotation, and didn't need the "DRIVE=" string included, you would change this:

Code: Select all

llRegionSay(channel, "DRIVE=" + (string)position + "=" + (string)rot);
to this:

Code: Select all

llRegionSay(channel, (string)position + "=" + (string)rot);
And, don't forget, you can also just pick up the c/m/t package in Furthermore.
These users thanked the author Sherrie Melody for the post (total 4):
Constance PeregrineDot MatrixMin TigerpawSarge Misfit
Post Reply