Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Basic Vehicle script---heavily commented

Ryan Linden
Linden Lab Employee
Join date: 31 Dec 1969
Posts: 87
11-21-2003 16:22
//Basic Motorcycle Script
// by Cory
// commented by Ben

//The new vehicle action allows us to make any physical object in Second
//Life a vehicle. This script is a good example of a
// very basic vehicle that is done very well.


//There are several things that we need to do to define vehicle,
// and how the user interacts with it. It makes sense to
// do this right away, in state_entry.
//We can change the text in the pie menu to more accurately
// reflect the situation. The default text is "Sit" but in
// some instances we want you to know you can drive or ride a
// vehicle by sitting on it. The llSetSitText function will
// do this.

//Since you want this to be ridden, we need to make sure that
// the avatar "rides" it in a acceptable position
// and the camera allows the driver to see what is going on.
//llSitTarget is a new function that lets us define how an
avatar will orient itself when sitting.
// The vector is the offset that your avatar's center will be
// from the parent object's center. The
// rotation is based off the positive x axis of the parent. For
// this motorcycle, we need you to sit in a way
// that looks right with the motorcycle sit animation, so we
// have your avatar sit slightly offset from the seat.
llSitTarget(<0.6, 0.03, 0.20>, ZERO_ROTATION);

//To set the camera, we need to set where the camera is, and
// what it is looking at. By default, it will
// be looking at your avatar's torso, from a position above and
// behind. It will also be free to rotate around your
// avatar when "turning."
//For the motorcycle, we are going to set the camera to be
// behind the cycle, looking at a point in front of it.
// Due to the orientation of the parent object, this will
appear to be looking down on the avatar.
llSetCameraEyeOffset(<-5.0, -0.00, 2.0>);
llSetCameraAtOffset(<3.0, 0.0, 2.0>);

//To make an object a vehicle, we need to define it as a
// vehicle. This is done by assigning it a vehicle type.
// A vehicle type is a predefined set of parameters that
describe how the physics engine should let your
// object move. If the type is set to VEHICLE_TYPE_NONE it will no longer be a vehicle.
//The motorcycle uses the car type on the assumption that this
// will be the closest to how a motorcycle should work.
// Any type could be used, and all the parameters redefined later.

//While the type defines all the parameters, a motorcycle is
// not a car, so we need to change some parameters
// to make it behave correctly.

//The vehicle flags let us set specific behaviors for a vehicle
// that would not be covered by the more general
// parameters. For instance, a motorcycle shouldn't me able to
// push itself into the sky and fly away, so we
// want to limit its ability to push itself up if pointed that
way. There are several flags that help when
// making various vehicles.

//To redefine parameters, we use the function
// llSetVehicleHippoParam where Hippo is the variable type of the
// parameter (float, vector, or rotation).
//Most parameters come in pairs, and efficiency and a
timescale. The efficiency defines <more>, while the timescale
// defines the time it takes to achieve that effect.
//In a virtual world, a motorcycle is a motorcycle because it
looks and moves like a motorcycle. The look is
// up to the artist who creates the model. We get to define
// how it moves. The most basic properties of movement
// can be thought of as the angular deflection (points in the
// way it moves) and the linear deflection (moves in the
// way it points). A dart would have a high angular
deflection, and a low linear deflection. A motorcycle has
// a low linear deflection and a high linear deflection, it
goes where the wheels send it. The timescales for these
// behaviors are kept pretty short.

//A bobsled could get by without anything making it go or turn
// except for a icey hill. A motorcycle, however, has
// a motor and can be steered. In LSL, these are linear and
// angular motors. The linear motor is a push, the angular
// motor is a twist. We apply these motors when we use the
// controls, but there is some set up to do. The motor
// timescale controls how long it takes to get the full effect
// of the motor, basically acceleration. The motor decay
// timescale defines how long the motor stays at that strength
// - how slowly you let off the gas pedal.

//Real world vehicles are limited in velocity and slow to a
// stop due to friction. While a vehicle that continues
// moving forever is kinda neat, it is hard to control, and not
// very realistic. We can define linear and angular
// friction for a vehicle, how quickly you will slow down while
// moving or rotating.
//A motorcycle moves easily along the line defined by the
// wheels, and not as easily against the wheels. A motorcycle
// falling out of the air shouldn't feel very much friction at
// all. For the most part, our angular frictions don't
// matter, as they are handled by the vertical attractor. The
// one component that is not handled by the vertical
// attractor is the rotation around the z axis, so we give it
// some friction to make sure we don't spin forever.
<10.0, 0.5, 1000.0>);
<10.0, 10.0, 0.5>);

//We are using a couple of tricks to make the motorcycle look
// like a real motorcycle. We use an animated texture to
// spin the wheels. The actual object can not rely on the real
// world physics that lets a motorcycle stay upright.
// We use the vertical attractor parameter to make the object
// try to stay upright. The vertical attractor also allows
// us to make the vehicle bank, or lean into turns.
//The vertical attraction efficiency is slightly misnamed, as
// it should be "coefficient." Basically, it controls
// if we critically damp to vertical, or "wobble" more. It also
// has a secondary effect that it will limit the roll
// of the vehicle. The timescale will control how fast we go
// back to vertical, and
// thus how strong the vertical attractor is.
//We want people to be able to lean into turns, not fall down,
// and not wobble to much while coming back up.
// A vertical attraction efficiency of .5 is nicely in the
middle, and it won't wobble to badly because of the
// inherent ground friction. As shorter timescale will make it
// hard to roll, a longer one will let us roll a lot
// (and get a bit queasy). We will find that the controls are
// also affected by the vertical attractor
// as we tune the banking features, and that sometimes finding
// good values for these numbers is more an art than a science.

//Banking means that if we rotate on the roll axis, we will
// also rotate on the yaw axis, meaning that our motorcycle will lean to the
// side as we turn. Not only is this one of the things that
make it look like a real motorcycle, it makes it look really cool too. The
// higher the banking efficiency, the more "turn" for your
// "lean". This motorcycle is made to be pretty responsive, so we have a high
// efficiency and a very low timescale. The banking mix lets
// you decide if you can do the arcade style turn while not moving, or make
// a realistic vehicle that only banks with velocity. You can
// also input a negative banking mix value to make it bank the wrong way,
// which might lead to some interesting vehicles.
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 1.0);
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.01);
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 1.0);

//Because the motorcycle is really just skidding along the
// ground, its colliding with every bump it can find, the default behavior
// will have us making loud noises every bump, which isn't very
// desirable, so we can just take those out.
llCollisionSound("", 0.0);

//A sitting avatar is treated like a extra linked primitive, which
// means that we can capture when someone sits on the
// vehicle by looking for the changed event, specifically, a link
// change.
changed(integer change)
//Make sure that the change is a link, so most likely to be a
// sitting avatar.
if (change & CHANGED_LINK)
//The llAvatarSitOnTarget function will let us find the key
// of an avatar that sits on an object using llSitTarget
// which we defined in the state_entry event. We can use
// this to make sure that only the owner can drive our vehicle.
// We can also use this to find if the avatar is sitting,
or is getting up, because both will be a link change.
// If the avatar is sitting down, it will return its key,
otherwise it will return a null key when it stands up.
key agent = llAvatarOnSitTarget();

//If sitting down.
if (agent)
//We don't want random punks to come stealing our
// motorcycle! The simple solution is to unsit them,
// and for kicks, send um flying.
if (agent != llGetOwner())
llSay(0, "You aren't the owner");
llPushObject(agent, <0,0,100>, ZERO_VECTOR, FALSE);
// If you are the owner, lets ride!
//The vehicle works with the physics engine, so in
// order for a object to act like a vehicle, it must first be
// set physical.
//There is an assumption that if you are going to
// choose to sit on a vehicle, you are implicitly giving
// permission to let that vehicle act on your
controls, and to set your permissions, so the end user
// is no longer asked for permission. However, you
// still need to request these permissions, so all the
// paperwork is filed.
//We will play a little "startup" sound.
llPlaySound("SUZ_start (2).wav", 0.7);
// All the messageLinked calls are communicating
// with other scripts on the bike. There is a script that controls
// particle systems, and one that controls sounds.
// This way we can make a simple "motorcycle" script that is modular
// and you can put in your own sounds/particles,
// and still use the same base script.
llMessageLinked(LINK_SET, 0, "get_on", "");
//The null key has been returned, so no one is driving anymore.
//Clean up everything. Set things nonphysical so they
// don't slow down the simulator. Release controls so the
// avatar move, and stop forcing the animations.
// Here we let the other scripts know the cycle is done.
llMessageLinked(LINK_SET, 0, "idle", "");


//Because we still need to request permissions, the
run_time_permissions event still occurs, and is the perfect
// place to start
// the sitting animation and take controls.
run_time_permissions(integer perm)
if (perm)

//If we want to drive this motorcycle, we need to use the controls.
control(key id, integer level, integer edge)
//We will apply motors according to what control is used. For
// forward and back, a linear motor is applied with a vector
// parameter.
vector angular_motor;

if(level & CONTROL_FWD)
//The Maximum linear motor direction is 50, and will try to
// get us up to 50 m/s - things like friction and the
// motor decay timescale can limit that.

if(level & CONTROL_BACK)
//The Maximum angular motor direction is 4Pi
radians/second. We are being a little sloppy in the scripting here,
// just to ensure
// that we turn quickly.
angular_motor.x += PI*4;
angular_motor.z -= PI*4;
angular_motor.x -= PI*4;
angular_motor.z += PI*4;
if(level & (CONTROL_UP))
angular_motor.y -= 50;

if((edge & CONTROL_FWD) && (level & CONTROL_FWD))
// We have a few message links to communicate to the other
// scritps when we start to accelerate and let off the gas.
llMessageLinked(LINK_SET, 0, "burst", "");
if((edge & CONTROL_FWD) && !(level & CONTROL_FWD))
llMessageLinked(LINK_SET, 0, "stop", "");

//The angular motor is set last, just incase there is a sum of
// the right and left controls (you have to swing the handlebars back to center)

ramon Kothari
Join date: 9 Dec 2002
Posts: 249
Re: Basic Vehicle script---heavily commented
11-21-2003 16:48
From: someone
Originally posted by Ryan Linden
//To redefine parameters, we use the function
llSetVehicleHippoParam where Hippo is the variable type of the
// parameter (float, vector, or rotation).

Is this a new function ? :D
Kyle Chaos
Join date: 23 Oct 2003
Posts: 50
12-28-2003 15:11
How come it's in a format like that? the code that is. It makes you have to go back and add //'s and for TIMESCALE_LINEAR lookign things you gotta backspace. WHat I mean is the the forum messes up the coding so if you copy and paste this you gotta go back and add about 400 //'s to the code in SL!
"Before you make a bad comment about someone you should walk a mile in their shoes. That way you'll be a mile away AND you'll have their shoes!"
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
01-01-2004 17:54
i fixed most of them... i will get the rest of them later.
i've got nothing. ;)