Jump to content

Need help with a camera tracking an object


Ross Mistwalker
 Share

You are about to reply to a thread that has been inactive for 2814 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi there, im not the best at scripting and I got a bunch of help to get this far, but It still wont work right.

What I'm working on is a remote control helicopter, and when I wear an object I want the camera view to be above the avatar slightly and be constantly focused on the helicopter, similar as in real life, where you would stand in the same spot, watching the helicopter fly where it goes.

I cannot get the camera to focus on the object.

This is the script thats placed in the helicopter to give the other object its position:

default
{
    state_entry()
    {
        llSetTimerEvent(0.1);
    }
    timer()
    {
       
        llRegionSay(-991119 , (string)llGetPos());
    }

}

 This is the script that is placed in the object the user wears:

focus_on_me()
{

    vector here = llGetPos();
    llSetCameraParams([
        CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive
        CAMERA_BEHINDNESS_ANGLE, 0.0, // (0 to 180) degrees
        CAMERA_BEHINDNESS_LAG, 0.0, // (0 to 3) seconds
        CAMERA_DISTANCE, 1.0, // ( 0.5 to 10) meters
        CAMERA_FOCUS, here, // region relative position
        CAMERA_FOCUS_LAG, 0.0 , // (0 to 3) seconds
        CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)
        CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) meters
//        CAMERA_PITCH, 80.0, // (-45 to 80) degrees
        CAMERA_POSITION, here, // region relative position
        CAMERA_POSITION_LAG, 1.0, // (0 to 3) seconds
        CAMERA_POSITION_LOCKED, TRUE, // (TRUE or FALSE)
        CAMERA_POSITION_THRESHOLD, 0.0, // (0 to 4) meters
        CAMERA_FOCUS_OFFSET, pos // <-10,-10,-10> to <10,10,10> meters
    ]);
}
vector pos;
default
{
    timer()
    {
        focus_on_me();
    }
    touch_start(integer tt)
    {
        
    }
    state_entry()
    {
        llSetTimerEvent(0.1);
        llListen(-991119, "", "", "");
      llRequestPermissions(llGetOwner(), PERMISSION_CONTROL_CAMERA);
    }
    listen(integer channel, string name, key id, string message)
    {
        if(message)
        {
            pos = (vector)message;
        }
    }
    run_time_permissions(integer perm) {
        if (perm & PERMISSION_CONTROL_CAMERA) {
            llSetCameraParams([CAMERA_ACTIVE, 1]); // 1 is active, 0 is inactive
            llOwnerSay("Camera permissions have been taken");
            llClearCameraParams(); // reset camera to default
        }
    }
 
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            key agent = llAvatarOnSitTarget();
            if (agent)
            {
                llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
            }
        }
    }
 
    attach(key agent)
    {
        if (agent)
        {
           
            llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
        }
    }
}

 I hope someone knows more than I do. :matte-motes-dont-cry:

Link to comment
Share on other sites

Sorry, id like to add that I've no idea of this version, I was randomly changing the variables in an effort to get it to work, the cameras position would idealy be the position of the attached object.

 

But surely the camera position is where the camera looks from, I only want the camera to simply look and track the object through the air, not follow behind the object.

And yeah, I tried it like you said beforehand at some point, but I just kept switching them round like I said to try and make it work.

Link to comment
Share on other sites

The camera's position better be pretty close to the target if you're going to get a view from there, not halfway across the sim.  And the focus should be too.  Look at the default position of your viewer's camera, for comparison.  The camera position is behind you by about 3m and above by about 1m.  Its focus is a few meters ahead of you.  You want to replicate that same sort of relationship with respect to your helicopter.

Link to comment
Share on other sites

Clean it up, calm it down then tell us exactly what is and isn't happening and we'll walk through it step by step.

In the first place:

  1. Your helicopter timer is way too fast.  You probably don't need it anything like that fast and it's just causing extra work for everything, possibly overloading the camera-controller so it just can't keep up anyway.  Slow it down - 1s should be fast enough to get it working 'in principle', then you can speed it up to what you really need.
  2. You don't need or want a timer in the controller script.  Focussing should be controlled by the receipt of a message from the helicopter.  Remove the timer() event-handler.
  3. Touch_start() is empty and redundant.  Remove it.
  4. You'll be wearing the controller so requesting permission is best in attach() and everything else once permission is received.  Remove state_entry().
  5. Remove changed() - you'll be wearing it, not sitting on it.

It's very easy to get in a bit of a mess when you've been trying all sorts of variations.  When you're in a hole, stop digging :-)

With a smaller, cleaner, simpler script your attach() handler asks for permission (as now, that's fine), run_time_permissions() opens the listen and listen() calls focus_on_me().  Rollig and others will probably say the focussing code should be put inline in the listen() handler but I like the fact that with it separate you can easily add back control by sitting instead of wearing.  It makes sense to parameterise the function though - focus_on_me(vector Position).  With a bit of checking of the message that leaves you with:

// Shared Data (must be the same in the other script// -------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";focus_on_me(vector Position){	// ..... Lots of interesting control code here}default{	attach(key ID){		if(NULL_KEY != ID){			llRequestPermissions(ID, PERMISSION_CONTROL_CAMERA);		}	}	listen(integer ChannelIn, string FromName, key FromID, string Message){		if((CommsChannel == ChannelIn) && (FromName == TargetName)){			vector Target = (vector) Message;			if(ZERO_VECTOR != Target){				focus_on_me(Target);			}		}	}	run_time_permissions(integer Perms){		if(Perms & PERMISSION_CONTROL_CAMERA){			llListen(CommsChannel, TargetName, "", "");		}	}}

 And for the helicopter:

// Shared Data (must be the same in the other script// -------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";default{	state_entry(){		llSetObjectName(TargetName);		llSetTimerEvent(1.0);	}	timer(){		llRegionSay(CommsChannel, (string) llGetPos());	}}

 Of course, you'll have noticed the minor fact that there's no focus code here ... I'm just starting to investigate that ...

  • Like 1
Link to comment
Share on other sites

Alright; the main problem I found was the camera believes the avatar is its target and keeps looking back there.  This means you must set and lock the focus position.  Just in case the avatar does decide to walk around while using this I'm also setting and locking the camera's own position (at 1.5m above the avatar in this example).  Replace the 'dummy' focus_on_me() routine above with:

focus_on_me(vector Position){	llSetCameraParams([CAMERA_ACTIVE, 1,		CAMERA_FOCUS, Position,		CAMERA_FOCUS_LOCKED, TRUE,		CAMERA_POSITION, llGetPos() + <0.0, 0.0, 1.5>,		CAMERA_POSITION_LOCKED, TRUE]);}

 

It's not smooth so unfortunately the update messages from the helicopter do have to be fast.

If anyone else wants to try this.  I amended the helicopter's comms script to make this simple target drone:

// Shared Data (must be the same in the other script)// --------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";default{	on_rez(integer StartParam){		llResetScript();	}	state_entry(){		llSetObjectName(TargetName);		llSetTimerEvent(0.1);		llSetKeyframedMotion([<5.0, 0.0, 0.0>, 5.0, <-5.0, 0.0, 0.0>, 5.0], [KFM_MODE, KFM_LOOP, KFM_DATA, KFM_TRANSLATION]);	}	timer(){		llRegionSay(CommsChannel, (string) llGetPos());	}}

 

  • Like 1
Link to comment
Share on other sites

Hi, thanks for your help, unfortunately, it doesn't seem to work, I think I must be doing something wrong.

 

I placed this script in my RC Helicopter:

// Shared Data (must be the same in the other script// -------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";default{    state_entry(){        llSetObjectName(TargetName);        llSetTimerEvent(1.0);    }    timer(){        llRegionSay(CommsChannel, (string) llGetPos());    }}

 

And then I placed this script, which I amended as per your instructions into a simple primitive cube for debugging:

// Shared Data (must be the same in the other script// -------------------------------------------------integer CommsChannel = -991119;string TargetName = "Helicopter";focus_on_me(vector Position){    llSetCameraParams([CAMERA_ACTIVE, 1,        CAMERA_FOCUS, Position,        CAMERA_FOCUS_LOCKED, TRUE,        CAMERA_POSITION, llGetPos() + <0.0, 0.0, 1.5>,        CAMERA_POSITION_LOCKED, TRUE]);}    // ..... Lots of interesting control code heredefault{    attach(key ID){        if(NULL_KEY != ID){            llRequestPermissions(ID, PERMISSION_CONTROL_CAMERA);        }    }    listen(integer ChannelIn, string FromName, key FromID, string Message){        if((CommsChannel == ChannelIn) && (FromName == TargetName)){            vector Target = (vector) Message;            if(ZERO_VECTOR != Target){                focus_on_me(Target);            }        }    }    run_time_permissions(integer Perms){        if(Perms & PERMISSION_CONTROL_CAMERA){            llListen(CommsChannel, TargetName, "", "");        }    }}

 I then wear the primitive cube and attach it to my neck (empty slot), I then rez the helicopter with the new script in, but the camera doesn't change, it simply stays as though nothing had happened and the camera remains behind the avatar and does not seem to move or change. Scripts are enabled in the land im on.

Link to comment
Share on other sites

I tried it, and this works as-is for me.

Just in case it's not clear: The scripted cam is the "default" cam -- what you get when you press the Escape key a time or two, to get out of any alt-zooming you may have done.

I'm not crazy about the details of this script (e.g., the Helicopter doesn't need to keep sending out its position once the cam-controlling script knows its UUID and can get the target position with llGetObjectDetails()), but at least it's working.

Link to comment
Share on other sites

Absolutely Qie.  I stuck with fast llRegionSay() just to keep things simple.  Using llGetObjectDetails() would need an initial handshake of some sort before changing operation and also checking that the target was still in the sim, which all seemed a bit much for a 'proof of concept'.  Is llGetObjectDetails() any less laggy though?  As soon as I start using sub-second timers for anything I start to cringe.

This is the first time I've with scripted camera controls, does anyone know of a smooth(er) way to move it?

I'm considering a forced-mouselook vehicle that uses a prediction algorithm to rotate itself instead.  If I can be bothered ...

Link to comment
Share on other sites

I've tested again and setup is about as simple as it can be so there may be a conflict between how you're controlling the helicopter and the camera-focussing.  So the first question, "does any of this work for you?"

Just so you have a moving test object: rez a prim and put that 'drone' script in it.  The drone should move backwards and forwards along the x dimension.  If it does not move reset the script in it (I added a reset on rez to mine but it should work manually).  If the drone won't move the first thing to consider is whether scripts are enabled on that land.

Now rez another cube for the camera controller:  just leave the drone moving around and rez another prim and put the controller script in it.  Nothing should happen.  Give this prim a name so you can find it in inventory and 'take' it.  Open your inventory, find the prim you've just taken and 'wear' it (attachment point shouldn't matter).  The camera should immediately be moved to just above your avatar (1.5m above its centre actually, but that should be 'above') and should update its focus position to look at the drone every time it receives the position message.  If the camera does not move at all make sure all edit/build windows are closed and press Escape a couple of times.  If this cures it then you had alt-zoomed on something with the mouse, which overrides any scripted camera controls (as Qie said).  Alt-zooming on something will stop the camera tracking the drone and esc will re-start it.  Detaching the controller will return your camera to default operation and re-attaching it will start it again.

If this is still not working for you the next step is to check communications.  In the controller's listen() event-handler add a line just before the focus_on_me() call.  "llOwnerSay("Updated: " + Message);" - this will tell you every time the controller receives a valid message from the helicopter.    In theory anyway .... what results do you get?

Link to comment
Share on other sites

  • 4 years later...

Greetings! Saw this post and the script is very useful. I would like to ask if there is a way by modifying this script so the avatar has the option to "view as the moving object"? please? In other words, instead of viewing from the avatar looking at the moving object; the camera is forced above the move object --- from the perspective of the moving object please? Any help will be great please... I really do not know much about scripting; if you can kindly please post the code on how to do this, it will be of great help. Thank you very much in advance kiki

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2814 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...