Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Help with bike script

Osvaldo Romeo
Registered User
Join date: 30 Jul 2006
Posts: 2
08-18-2006 08:26
Ive been trying to make a script for a new bike, and ive modified this script posted by Ryan Linden, but i can't make it work.

The avatar sits on the bike, starts the 'motorcycle_sit' animation, and take controls, but it does't MOVE (in any direction).

Can anyone that knows something of vehicle scripting help me out here.

CODE

default
{
state_entry()
{

llSetSitText("Get In!");
llCollisionSound("", 0.0);
llSitTarget(<0.03, 0.05, 0.30>, ZERO_ROTATION);
llSetCameraEyeOffset(<-5, -0.00, 2.0>);
llSetCameraAtOffset(<3.0, 0.0, 2.0>);

llSetVehicleType(VEHICLE_TYPE_CAR);

llSetVehicleFlags(VEHICLE_FLAG_NO_DEFLECTION_UP | VEHICLE_FLAG_LIMIT_ROLL_ONLY | VEHICLE_FLAG_LIMIT_MOTOR_UP);


llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 1);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.2);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.5);

llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <100.0, 0.5, 1000.0>);
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <1000, 1000, 1000>);

llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 1);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.40);

llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0);
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.01);
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 1.0);

llCollisionSound("", 0.0);

}

changed(integer change)
{
if (change & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
string a =llKey2Name(agent);
llSay (0,"welcome" + a);


if (agent != NULL_KEY)
{
if (agent != llGetOwner())
{
llSay(0, a + "You are not the owner");
llUnSit(agent);
llPushObject(agent, <0,0,100>, ZERO_VECTOR, FALSE);
}
else
{
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
llMessageLinked(LINK_SET, 0, "get_on", "");
}
}
else
{
llSetStatus(STATUS_PHYSICS, FALSE);
llReleaseControls();
llMessageLinked(LINK_SET, 0, "idle", "");
}
}

}

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);
}
}

control(key id, integer level, integer edge)
{
vector angular_motor;

if(level & CONTROL_FWD)
{
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<25,0,0>);

}
if(level & CONTROL_BACK)
{
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<-25,0,0>);
}
if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
{
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))
{
llMessageLinked(LINK_SET, 0, "burst", "");
}
if((edge & CONTROL_FWD) && !(level & CONTROL_FWD))
{
llMessageLinked(LINK_SET, 0, "stop", "");
}

llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);
}

}




Thanks.
Osvaldo Romeo
Tiarnalalon Sismondi
Registered User
Join date: 1 Jun 2006
Posts: 402
08-18-2006 12:45
Well...it appears to me that the controls are lacking quite a bit of code. The motors should be set by using vectors that are changed by the user inputs and then applied in a timer event.

When the bike starts, it should have an timer trigger and the lines for llSetVehicleVectorParam(); should be inside there and not in the control() section

Edit: Just read through the code a bit more...

You also have the forward and back controls duplicated.

level & edge refer to when you hold the key and when you let go.

You have it set to just send a link message for either at the bottom of the control if's.
Azurei Ash
The Sticky!
Join date: 12 Jan 2006
Posts: 38
08-18-2006 14:29
Actually, it looks fine to me.

This may sound stupid, but you did get physics enabled properly on the bike?

From: Tiarnalalon Sismondi
Well...it appears to me that the controls are lacking quite a bit of code. The motors should be set by using vectors that are changed by the user inputs and then applied in a timer event.

When the bike starts, it should have an timer trigger and the lines for llSetVehicleVectorParam(); should be inside there and not in the control() section

That is a valid way of doing it, but personally I hate vehicles that drive that way.

As written in the code above, the
CODE
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<25,0,0>);

line will thrust the vehicle forward by setting the linear motor's direction vector, and this will happen every control event as long as the forward button is held down.... that way if you let go, you will slow down to a stop according to the other vehicle parameters that control how quickly the linear motor degrades.

From: Tiarnalalon Sismondi

Edit: Just read through the code a bit more...

You also have the forward and back controls duplicated.

level & edge refer to when you hold the key and when you let go.

You have it set to just send a link message for either at the bottom of the control if's.


Level and edge sound like words an Electrical Engineer would use (nothing against EE, I'm just a CS major o_-), I prefer held and change myself. But the way it works is bits in level/held indicate whether each key is up or down and bits in edge/change indicate whether or not a key just changed position (ie a 1 indicates that either the key was just pressed or just release, you have to check level/held if you need to know which)

So testing:
CODE
if((edge & CONTROL_FWD) && (level & CONTROL_FWD))

first checks that the forward key changed its state and then that it is held down, together these indicate that it was just pressed. This prevents this condition from being true in the next control event when the forward key may still be held. It only happens on the initial press.

It does make sense that way since two things are beign checked, but you can also just test the same thing like this:
CODE
if(edge & level & CONTROL_FWD)


This becomes less logical though when you try to do the other case where edge is true and level is false (key release):
CODE
if(edge & ~level & CONTROL_FWD)


You could also move it up into the "if(level & CONTROL_FWD)" turning it into a nested if statement that includes "if(edge & CONTROL_FWD)", ie it would become:

CODE
if(level & CONTROL_FWD) 
{
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIREC TION,<25,0,0>);
if(edge & CONTROL_FWD)
{
llMessageLinked(LINK_SET, 0, "burst", "");
}
}


But there's not much difference, and which you want may depend on whether or not you think of them logically as separate cases and whether or not you value the forward case looking similar to the backward case.

Anyway, if you do have physics properly enabled and still haven't gotten it working yet, post again.

Another thing to check is the orientation of your root prim. It will thrust relative to that orientation, which is hopefully correct. It doesn't move at all?

~Az
Osvaldo Romeo
Registered User
Join date: 30 Jul 2006
Posts: 2
08-18-2006 21:38
But there's not much difference, and which you want may depend on whether or not you think of them logically as separate cases and whether or not you value the forward case looking similar to the backward case.

Anyway, if you do have physics properly enabled and still haven't gotten it working yet, post again.

Another thing to check is the orientation of your root prim. It will thrust relative to that orientation, which is hopefully correct. It doesn't move at all?

I do have the physics enabled, i dont know if properly. It is done here...

CODE

changed(integer change)
{
if (change & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
string a =llKey2Name(agent);
llSay (0,"welcome" + a);


if (agent != NULL_KEY)
{
if (agent != llGetOwner())
{
llSay(0, a + "You are not the owner");
llUnSit(agent);
llPushObject(agent, <0,0,100>, ZERO_VECTOR, FALSE);
}
else
{
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
llMessageLinked(LINK_SET, 0, "get_on", "");
}
Osvaldo Romeo
Registered User
Join date: 30 Jul 2006
Posts: 2
08-18-2006 21:43
I do have the physics enabled, i dont know if properly. It is done here...(in the changed function.

CODE


else
{
llSetStatus(STATUS_PHYSICS, TRUE);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
llMessageLinked(LINK_SET, 0, "get_on", "");
}


And about the orientation, its exactly the same that the world ruler. Ive even created a new prim (root prim) to make sure of it.

And, no, it doesn't move at all (doesn't even turn).
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-18-2006 22:42
You'll want to set the linear motor timescale to a smaller value than the linear motor decay timescale, I think. Otherwise it looks okay. You don't necessarily need timers actually. :-)