Shortnote

Suitable for motocycle-type vehicles.

Code

motocycle.lsl
//Basic Motorcycle Script
//
// by Cory
// commented by Ben
// Last edited by Nada Epoch on 01-01-2004 at 08:51 PM
 
//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.
 
default
{
 
    //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.
    state_entry()
    {
        llPassCollisions(TRUE);
        //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.
        llSetSitText("Ride");
 
        //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(<.6, .03, .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, -.00, 2> );
        llSetCameraAtOffset(<3, .0, 2> );
 
 
        //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.
        llSetVehicleType(VEHICLE_TYPE_CAR);
 
 
        //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.
        llSetVehicleFlags(VEHICLE_FLAG_NO_DEFLECTION_UP | VEHICLE_FLAG_LIMIT_ROLL_ONLY | VEHICLE_FLAG_LIMIT_MOTOR_UP);
 
        //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.
         llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, .2);
         llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, .80);
         llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, .10);
         llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, .10);
 
        //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.
         llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1);
         llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, .2);
         llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, .1);
         llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, .5);
 
        //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.
         llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, .5, 1000.0> );
         llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <10.0, 10.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.
         llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, .50);
         llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, .40);
 
        //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  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);
        llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, .01);
        llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 1);
 
        //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);
    }
 
 
    //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");
                    llUnSit(agent);
                    llPushObject(agent, <0,0,100>, ZERO_VECTOR, FALSE);
                }
                // If you are the owner, lets ride!
                else
                {
                    //The vehicle works with the physics engine, so in 
                    // order for a object to act like a vehicle, it must first be
                    // set physical.
                    llSetStatus(STATUS_PHYSICS, TRUE);
                    //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.
                    llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
                    //We will play a little "startup" sound.
                    llPlaySound("SUZ_start (2).wav", .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.
            else
            {
                //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.
                llSetStatus(STATUS_PHYSICS, FALSE);
                llReleaseControls();
                llStopAnimation("motorcycle_sit");
                // 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)
        {
            llStartAnimation("motorcycle_sit");
            llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE);
        }
    }
 
    //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.
             llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <50,0,0> );
 
        }
        if(level & CONTROL_BACK)
        {
             llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <-20,0,0> );
        }
        if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
        {
            //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;
        }
        if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
        {
            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)
         llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,angular_motor);
    }
 
}

secondlife/engines/motocycle.txt ยท Last modified: 2022/11/24 07:46 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.