llSitTarget(vector offset, rotation rot)

Sets the sit target for the prim (not the object) at offset from the center of the prim and rotated by rot. If offset is ZERO_VECTOR, the sit target is cleared.

After defining a sit target, llAvatarOnSitTarget can be used. The changed event will be called with the CHANGED_LINK flag set when someone sits on the prim, at which time llAvatarOnSitTarget may be called.

Note: like particles, sit targets are a property of the prim, not the script. So if a script gives a prim a sit target, and that script is deleted, the sit target remains. The only way to clear the sit target is by calling llSitTarget(ZERO_VECTOR,ZERO_ROTATION);

Example:

// Avatar will sit slightly above the object's center, 
// facing the direction of the forward axis.
llSitTarget(<0,0,.1>, ZERO_ROTATION);
//This rotates the avatar 90 degrees
llSitTarget(<0,0,0.1>,llEuler2Rot(<0,0,90> * DEG_TO_RAD));

Offset Problems With Sit Animations

It would be nice if one llSitTarget setting would suffice for all occasions. Sadly, it does not, because visual placement of avatar in llStartAnimation is in itself dependent on avatar size, build, and — surprise — gender! You may get it just right for your own avatar, but the next visitor with different gender sits with unacceptable offset — or can’t sit at all because of it.

It gets worse when using some custom sit animations! The same sit-target and animation can result in relative offset of half a meter, or more, between male and female avatars. The only way to determine if sit target + animation + gender + avatar-size is a serious problem is to test and test again. Maybe a compromise target location can split the differences acceptably. Maybe you need to make some placements M or F only. Maybe you can include script runtime tests to dynamically adjust target before (re)setting it, or select alternative animations from a pre-chosen list.

Teleport Hack

The maximum distance llSitTarget can offset is up to 300m on any axis. This means it can be used to instantly teleport avatars around by having them sit on an object that immediately unsits them again (now at their new position). To activate the “teleporter”, the user simply selects “Sit Here” from the object’s pie menu. llSetSitText allows selecting a more apt label to replace “Sit Here”.

Note: the rotation of the object with the teleport script will usually affect where the teleport takes the avatar. To nullify this rotation, divide ZERO_ROTATION by the rotation of the object:

//Rotational cancel method by Moleculor Satyr
llSitTarget(target * (ZERO_ROTATION / llGetRot()),ZERO_ROTATION / llGetRot());

The location chosen in llSitTarget is a prim-local target, not a global one. To teleport-hack to a specific <x,y,z> position within the sim, subtract the object’s region coordinates from the target to obtain a vector that is relative to the object:

//Moleculor Satyr's rotational cancel with a tweak -Tateru Nino, and another -BW
vector target=<100.0, 100.0, 103.5>;
rotation my_rot = llGetRot();
llSitTarget((target - llGetPos()) / my_rot,ZERO_ROTATION / my_rot);

Note: in conditions of high lag and slow communications speed, SL will sometimes put the avatar close to <0,0,0> in the sim for sometime before actually putting the avatar in the sit location.

Also Note: The above example script will need to be reset each time the rotation or position is changed if the target is to be maintained.

Linked Objects With Multiple Sit Targets

How Seats Are Labeled

Wouldn’t it be nice if you could label the driver’s seat “Drive!” and the passenger’s seat “Ride!” But this does not seem possible 8-( . I’ve used llSetSitText to specify such seat labels. But, regardless, the label of the seat that is the root prim is used for every seat. 

Confusingly, despite having its label overriden by the root sit target’s label, the scripting of each individual sit target is still intact. You can test this by having each sit target llWhisper a unique message when you sit on it.

How We Choose Our Seats

In a vehicle (or any object) with multiple seats (each seat has a script that sets a sit target), the following method determines which sit target an avatar ends up at:

  • If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used.
  • If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used.

So, to make a vehicle that would allow one driver and exactly two passengers:

  • Link 0 (the root prim) the driver’s seat
  • Link 1 Passenger seat 1
  • Link 2 Passenger seat 2
  • Link 3 Ejector (a script that immediately llUnSits an avatar on its sit target)

So, if the vehicle is empty, and a player clicks on any unscripted part of the vehicle to sit, they will end up in the driver’s seat (the lowest empty link number with a sit target). 

  • If the driver’s seat is full they will end up in passenger seat 1.
  • If the driver’s seat and passenger seat 1 are full they will end up in seat 2.
  • If all seats are full, they will end up sitting on link 3 and be ejected.
  • If a player clicks on a specific seat and that seat is not full, they will sit there. If they click on link 3, they will be ejected, so you’d probably want to hide link 3 inside the vehicle where it cannot be clicked on.

Q and A

Q: Can I just set the sit target again to move a seated avatar?  Q: Can I move the child prim the avatar sited on to move the avatar?

A: Those techniques won’t work because the avatar starts to behave as a child prim once seated. For a workaround, see llSetLinkPrimitiveParams.