Difference between revisions of "Camera following prim"

From Second Life Wiki
Jump to navigation Jump to search
(Initial creation of page)
 
m (<lsl> tag to <source>)
 
(3 intermediate revisions by 2 users not shown)
Line 23: Line 23:
The CameraMaster (for the attachment):
The CameraMaster (for the attachment):


<lsl>
<source lang="lsl2">
// Put this in an attachment and it will continuously broadcast your camera position
// Put this in an attachment and it will continuously broadcast your camera position


Line 31: Line 31:
default
default
{
{
     state_entry() {
     attach(key id)
         // Nothing to do here really.
    {
         if (id != NULL_KEY)
            llRequestPermissions(id, PERMISSION_TRACK_CAMERA);
        else
            llSetTimerEvent((float)FALSE);
     }
     }
   
 
     on_rez(integer n) {
     run_time_permissions(integer perm)
         // Nor here.  I just put these in out of habit.
    {
         if (perm & PERMISSION_TRACK_CAMERA)
            llSetTimerEvent(DELAY);
     }
     }
   
 
     attach(key id) {
     timer()
         if (id != NULL_KEY) {
    {
            llRequestPermissions(id,PERMISSION_TRACK_CAMERA);
         vector cameraPosition = llGetCameraPos();
         } else {
 
            llSetTimerEvent(0.0);
         llRegionSay(CHANNEL, (string)cameraPosition);
        }     
     }
     }
   
    run_time_permissions(integer p) {
        llSetTimerEvent(DELAY);
    }
   
    timer() {
        llShout(CHANNEL,(string)llGetCameraPos());
    }
}
}
</lsl>
</source>


The follower, for the moving prim:
The follower, for the moving prim:


<lsl>
<source lang="lsl2">
// Put this in a non-physical prim, and it will move to (an offset from) places that it hears about.
// Put this in a non-physical prim, and it will move to (an offset from) places that it hears about.


integer CHANNEL = -85847;
integer CHANNEL = -85847;
vector OFFSET = ZERO_VECTOR;
vector OFFSET;


integer lh;
integer listenHandler;


init() {
init()
     llListenRemove(lh);
{
     lh = llListen(channel,"","","");
     llListenRemove(listenHandler);
}
     listenHandler = llListen(CHANNEL, "", NULL_KEY, "");
 
goto(vector dest) {
    /// One could use WarpPos or whatever here as well
    while ( llVecDist(llGetPos(),dest) > 0.1 ) {
        llSetPos(dest);
    }
}
}


default
default
{
{
     state_entry() {
     on_rez(integer start_param)
        init();
     {
     }
   
    on_rez(integer n) {
         llResetScript();
         llResetScript();
     }
     }
   
 
     changed(integer c) {
     changed(integer change)
         if (c & CHANGED_OWNER) {
    {
         if (change & CHANGED_OWNER)
             llResetScript();
             llResetScript();
        }
     }
     }
   
 
     listen(integer c, string n, key id, string msg) {
     state_entry()
         if ( llGetOwner() != llGetOwnerKey(id) ) return;
    {
        vector v = OFFSET + (vector)msg;
         init();
        goto(v);
     }
     }


    listen(integer channel, string name, key id, string message)
    {
        key owner = llGetOwner();
        key otherOwner = llGetOwnerKey(id);
        if (otherOwner != owner)
            return;
        vector destination = OFFSET + (vector)message;
        llSetRegionPos(destination);
    }
}
}
</lsl>
</source>


{{LSLC|Library}}{{LSLC|Examples}}
{{LSLC|Library}}{{LSLC|Examples}}

Latest revision as of 14:13, 24 January 2015

Introduction

A reasonably simple demo of a prim that follows your camera around (as long as you are wearing the special attachment that makes it work). This was inspired by a request for a light that would follow the camera around, but can be used for all sorts of other things as well. Presumably.

Usage

To use these scripts, stick the CameraMaster script into the root prim of an object, and wear that object. (Anywhere on the body; wearing it as a HUD attachment hasn't been tested.) Then stick the CameraFollowerPrim script into the prim that you want to follow your camera around (it should be a non-physical prim; phantom is probably also a good idea). As you move your camera around (alt-click and so forth, you know), the prim will follow the camera-point around (which can, for obvious reasons, make it hard to see the prim!).

Limitations and Notes

The prim that moves will move rather jerkily, but very fast. Smoother (but generally slower) motion could be gotten by making the moving prim physical, and using llMoveToTarget rather than llSetPos. If you prefer smoother motion for some reason. I haven't tried that variation, but it ought to be relatively simple.

You can change the channel that the scripts use to communicate, and the frequency with which it updates the prim's position, by altering the obvious constants in the code. You can also make the moving prim go to some offset from the camera position, rather than right on the camera position itself (a meter above it, say) by changing OFFSET in the follower script (to, say, <0,0,1>).

To make the prim stop following your camera, detach the attachment.

The Code

You may do anything you like with this code, without limitation. As far as I'm concerned. As long as it's not anything mean. You shouldn't be mean.

The CameraMaster (for the attachment):

// Put this in an attachment and it will continuously broadcast your camera position

float DELAY = 0.5;
integer CHANNEL = -85847;

default
{
    attach(key id)
    {
        if (id != NULL_KEY)
            llRequestPermissions(id, PERMISSION_TRACK_CAMERA);
        else
            llSetTimerEvent((float)FALSE);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRACK_CAMERA)
            llSetTimerEvent(DELAY);
    }

    timer()
    {
        vector cameraPosition = llGetCameraPos();

        llRegionSay(CHANNEL, (string)cameraPosition);
    }
}

The follower, for the moving prim:

// Put this in a non-physical prim, and it will move to (an offset from) places that it hears about.

integer CHANNEL = -85847;
vector OFFSET;

integer listenHandler;

init()
{
    llListenRemove(listenHandler);
    listenHandler = llListen(CHANNEL, "", NULL_KEY, "");
}

default
{
    on_rez(integer start_param)
    {
        llResetScript();
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
            llResetScript();
    }

    state_entry()
    {
        init();
    }

    listen(integer channel, string name, key id, string message)
    {
        key owner = llGetOwner();
        key otherOwner = llGetOwnerKey(id);

        if (otherOwner != owner)
            return;

        vector destination = OFFSET + (vector)message;
        llSetRegionPos(destination);
    }
}