Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: Realistic Car Script

Aaron Perkins
Registered User
Join date: 14 Nov 2003
Posts: 50
03-17-2004 12:55
This a respost from the other forum to mak it easier to find. Also you can get this script along with a sample car for L$1 at my shop. Look for the big glass tower (Rose, 158, 140).

Here is my submission to the community.

This a realistic car script. Three main features make it more realistic than your average car script.

1. You can't turn the car if you are not moving.

2. The tires rotate when you move and the front wheels turn when you turn.

3. Reverse steering works the right way.

There are three parts to this script.

1. car_main: Goes on the root prim of your vehicle. The "front" of the vehicle will the the postive X axis.

2. car_seat: Goes on each seat the vehicle has. The avatar's will be oreinted along the positive X axis when seated.

3. car_front and car_rear_wheel: Goes on the wheels of the vehicle.

I stole peices of code from all around these fourms to build this. So sorry if I offend anyone by releasing this.

car_main
CODE

//**********************************************
//Title: Car
//Author: Aaron Perkins
//Date: 3/17/2004
//**********************************************

//Feel free to modify these basic parameters to suit your needs.
float forward_power = 30; //Power used to go forward (1 to 30)
float reverse_power = -15; //Power ued to go reverse (-1 to -30)
float turning_ratio = 4.0; //How sharply the vehicle turns. Less is more sharply. (.1 to 10)
string sit_message = "Jump In!"; //Sit message
string not_owner_message = "You are not the owner of this vehicle ..."; //Not owner message

//Anything past this point should only be modfied if you know what you are doing
string last_wheel_direction;
string cur_wheel_direction;

default
{
state_entry()
{
llSetSitText(sit_message);

llSetCameraEyeOffset(<-10.0, 0.0, 2.0>);
llSetCameraAtOffset(<10.0, 0.0, 2.0>);

//car
llSetVehicleType(VEHICLE_TYPE_CAR);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80);
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, <1000.0, 2.0, 1000.0>);
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <10.0, 10.0, 1000.0>);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.50);
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.50);
}

changed(integer change)
{
if (change & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
if (agent)
{
if (agent != llGetOwner())
{
llSay(0, not_owner_message);
llUnSit(agent);
llPushObject(agent, <0,0,50>, ZERO_VECTOR, FALSE);
}
else
{
llTriggerSound("car_start",1);

llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DRIVING", NULL_KEY);
llSleep(.4);
llSetStatus(STATUS_PHYSICS, TRUE);
llSleep(.1);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);

llSetTimerEvent(0.1);
llLoopSound("car_idle",1);
}
}
else
{
llSetTimerEvent(0);
llStopSound();

llSetStatus(STATUS_PHYSICS, FALSE);
llSleep(.1);
llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DEFAULT", NULL_KEY);
llSleep(.4);
llReleaseControls();

llResetScript();
}
}

}

run_time_permissions(integer perm)
{
if (perm)
{
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT |
CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE);
}
}

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

//get current speed
vector vel = llGetVel();
float speed = llVecMag(vel);

//car controls
if(level & CONTROL_FWD)
{
cur_wheel_direction = "WHEEL_FORWARD";
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <forward_power,0,0>);
reverse=1;
}
if(level & CONTROL_BACK)
{
cur_wheel_direction = "WHEEL_REVERSE";
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <reverse_power,0,0>);
reverse = -1;
}

if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
{
cur_wheel_direction = "WHEEL_RIGHT";
angular_motor.z -= speed / turning_ratio * reverse;
}

if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
{
cur_wheel_direction = "WHEEL_LEFT";
angular_motor.z += speed / turning_ratio * reverse;
}

llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);

} //end control

timer()
{
if (cur_wheel_direction != last_wheel_direction)
{
llMessageLinked(LINK_ALL_CHILDREN , 0, cur_wheel_direction, NULL_KEY);
last_wheel_direction = cur_wheel_direction;
}
}

} //end default


car_seat
CODE

//**********************************************
//Title: Car Seat
//Author: Aaron Perkins
//Date: 2/17/2004
//**********************************************

default
{
state_entry()
{
llSitTarget(<0,0,0.5>, llEuler2Rot(<0,-0.4,0>));
}

}


car_front_wheel
CODE

//**********************************************
//Title: Car Front Wheel
//Author: Aaron Perkins
//Date: 2/17/2004
//**********************************************

rotation Inverse(rotation r)
{
r.x = -r.x;
r.y = -r.y;
r.z = -r.z;
return r;
}
rotation GetParentRot()
{
return Inverse(llGetLocalRot())*llGetRot();
}
SetLocalRot(rotation x)
{
llSetRot(x*Inverse(GetParentRot()));
}

default
{
state_entry()
{
}

link_message(integer sender_num, integer num, string str, key id)
{
if(str == "WHEEL_DRIVING")
{
state driving;
}
}

}

state driving
{
state_entry()
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
llSetTimerEvent(0.5);
}

timer()
{
vector vel = llGetVel();
float speed = llVecMag(vel);
llSetTextureAnim(ANIM_ON|LOOP|SMOOTH|ROTATE,ALL_SIDES,0,0,0,0,speed);
}

link_message(integer sender_num, integer num, string str, key id)
{
if(str == "WHEEL_DEFAULT")
{
state default;
}

if(str == "WHEEL_FORWARD")
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
}

if(str == "WHEEL_REVERSE")
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
}

if(str == "WHEEL_LEFT")
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO, -1 * PI_BY_TWO / 2, 0>));
}

if(str == "WHEEL_RIGHT")
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO, PI_BY_TWO / 2, 0>));
}

}

state_exit()
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
llSetTextureAnim(0,ALL_SIDES,0,0,0,0,0);
}

}


car_rear_wheel
CODE

//**********************************************
//Title: Car Rear Wheel
//Author: Aaron Perkins
//Date: 2/17/2004
//**********************************************

rotation Inverse(rotation r)
{
r.x = -r.x;
r.y = -r.y;
r.z = -r.z;
return r;
}
rotation GetParentRot()
{
return Inverse(llGetLocalRot())*llGetRot();
}
SetLocalRot(rotation x)
{
llSetRot(x*Inverse(GetParentRot()));
}

default
{
state_entry()
{
}

link_message(integer sender_num, integer num, string str, key id)
{

if(str == "WHEEL_DRIVING")
{
state driving;
}

}

}

state driving

{
state_entry()
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
llSetTimerEvent(0.5);
}

timer()
{
vector vel = llGetVel();
float speed = llVecMag(vel);
llSetTextureAnim(ANIM_ON|LOOP|SMOOTH|ROTATE,ALL_SIDES,0,0,0,0,speed);
}

link_message(integer sender_num, integer num, string str, key id)
{
if(str == "WHEEL_DEFAULT")
{
state default;
}

}

state_exit()
{
SetLocalRot(llEuler2Rot(<-1 * PI_BY_TWO,0,0>));
llSetTextureAnim(0,ALL_SIDES,0,0,0,0,0);
}

}


Original Thread- /15/d0/11048/1.html
Paulo Parvenu
Registered User
Join date: 9 Sep 2004
Posts: 10
Hey
09-12-2004 21:56
Hey there,
How do you put a realistic body on the car like a BMW or Mercedes Benz Replica body on it?
Owl Patel
Fish miner.
Join date: 7 Jul 2004
Posts: 2,300
09-14-2004 11:06
You hav to be good at wat ur doing :) my style has always been cartoonish, so I dont make a whole lot of replicas, exept for my 'Calvin and Hobbes Spaceman Spiff Spaceship' (I hate typing tht wenever i mention it) The reason i just brot tht up is because I myself find it hard to leave my style, and work a diffrent way, its just not me. so, if ur style isnt, well, real life, ur probaly not going to get real life.
ArchTx Edo
Mystic/Artist/Architect
Join date: 13 Feb 2005
Posts: 1,993
05-30-2005 08:18
When i try to save the car_main script I get a message
(28, 60) : error : syntax error

what needs to be done to fix this?
_____________________

VRchitecture Model Homes at http://slurl.com/secondlife/Shona/60/220/30
http://www.slexchange.com/modules.php?name=Marketplace&MerchantID=2240
http://shop.onrez.com/Archtx_Edo
Tyg Jarrico
Registered User
Join date: 29 May 2005
Posts: 98
06-02-2005 06:00
I am very new. What keys do you use to move the car?
ArchTx Edo
Mystic/Artist/Architect
Join date: 13 Feb 2005
Posts: 1,993
06-07-2005 07:38
From: Tyg Jarrico
I am very new. What keys do you use to move the car?



The same keys u use to fly or walk around. However i had problems getting this script to work. i used the one in the wiki library with success. u could try this script in a single prim first to verify that it works ok.
_____________________

VRchitecture Model Homes at http://slurl.com/secondlife/Shona/60/220/30
http://www.slexchange.com/modules.php?name=Marketplace&MerchantID=2240
http://shop.onrez.com/Archtx_Edo
Racer Plisskin
Rezerator
Join date: 2 Jan 2005
Posts: 147
06-08-2005 19:48
I have a free 'learners kit' car by Aaron that uses his scripts above.

It's located on the corner of my car lot in the North, NorthEast section of Tavaru island. Do a 'find person' on me 'Racer Plisskin' and look under my places list if you have trouble finding it on the map.

Stop by and pick up a copy to play with and learn from. It's got full permissions on all parts & scripts. The 'free car' sign will give you a landmark to Aarons shop as well if you are interested.

Racer P.
_____________________
"What's important in life is not how many breaths we get to take but those moments that take our breath away." -- Jaques Cousteau

"A thin line separated serious homicidal purpose from buffoonery." -- Dean Koontz

"CanYouFixTheSpaceBarOnMyKeyboard?" -- Email to Helpdesk
Cornelius Bach
Lord of Typos
Join date: 30 Jul 2003
Posts: 241
06-09-2005 13:36
OMG! I'm going to take you to court over this! You have clearly stolen my code for this.. My script also contains "llSetVehicleType(VEHICLE_TYPE_CAR);" :P

(YES, JOKE)
_____________________

Corny

_________________________________
"I've got to go eat now" Andrew Palmerstone
Darzus Strutt
Registered User
Join date: 3 Sep 2003
Posts: 67
06-15-2005 02:09
From: Cornelius Bach
OMG! I'm going to take you to court over this! You have clearly stolen my code for this.. My script also contains "llSetVehicleType(VEHICLE_TYPE_CAR);" :P

(YES, JOKE)

Yep it is Corny comin from the king of Corn ...lol whats up man ...and u stole my shape..Prim shape Box :P
Lucas Sion
Registered User
Join date: 25 Aug 2005
Posts: 16
Exhaust Smoke/Flames
08-26-2005 17:32
Well the Title says it all, can we create a script the blows particles smoke or flame out of the exhaust pipe of the car? if anyone can, please post or gimme a copy in or out of game.
Thanks
Lucas Sion
Registered User
Join date: 25 Aug 2005
Posts: 16
Smoke/Flames
08-26-2005 17:34
Can we make a flames/smoke script for tailpipes?
Joey Fizz
Registered User
Join date: 3 May 2005
Posts: 3
11-27-2005 17:59
When i copy and paste it says there is an error wat do i do?
_____________________
Joey Fizz
Halo Hienzman
Registered User
Join date: 31 Jul 2006
Posts: 2
07-31-2006 11:07
This script sucks, no offence, i keep on falling through the ground and i cant turn
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
Turning wheels/seat
11-26-2006 14:47
I realiaze this thread is a bit old, but if there's anyone who could answer this, I'd greatly appreciate it.

I am making a bicycle, and it works well enough with this script (I put the script in a transparent base). Unfortunately, I simply cannot get the wheels to turn. I created the wheels from multiple prims, linked them together and put the script for the wheels in the root prim. Then I linked them and the rest together, using the base as the root prim for the vehicle. Nada. No turning at all, although the vehicle script works fine.

I also don't believe that the seat target is working. I put the script in a single prim seat, but the avatar sat on the base. I was able to move the avatar up to the seat by changing the variables for the sit target in the main vehicle script, but this seems inelegant, and that won't do the trick should I want to make a tandem bicycle.

While I'm at it, anyone have any good leads for a bicyclist animation?

Thanks!
Jolan Nolan
wannabe
Join date: 12 Feb 2006
Posts: 243
12-11-2006 19:06
Afaik, the only root prim you can have is the seat. All the rest are simply regular prims. You would have to make your wheels single prims, or put the script in the tire (part that touches the ground) for it to work. I would draw the spokes and inner parts then import as a TGA with transparency.

If you are making a bicycle, you may be better off with a free motorcycle script instead. While it doesn't come with the wheel or seat scripts, it should be easy enough to combine them.

*Also when going in reverse I have found that if there is no gas, the car turns the wrong way. If you turn to the left, the front of the car will move to the left regardless of rolling forwards or backwards.

- Jolan
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
bicycle construction
12-13-2006 07:05
Hi, there appear to be a few concepts to clarify here:

Firstly, there is only one link set per linked object, no hierarchy. So linking two linked objects together makes one big linked set containing all the parts, there is no way to distinguish what used to be front wheel or back wheel, and so it's not possible to rotate "just the front wheel prims" with a single wheel script. Each prim rotates/moves around its own local axis too, so their relative positions are not factored into their movement. The only prim which can move all the others is the root prim, the last one linked into the set.

The sit target for the seat prim will only be the default place to sit if no lower-numbered links (i.e., the root prim and any others linked in after the seat) have had a non-zero sit target set in them. If you have been experimenting, it's quite possible that the root prim once had a sit target set in it, by some other vehicle or pose script. This setting is like particles, it remains set even after the script is removed, so in order to clear that out, you can use a short script (or just put a line into the default state_entry of an existing script) to set the sit target position and rotation back to zero, allowing the seat prim's sit target to be chosen over other prims when Sit is chosen. The line is:

llSitTarget ( ZERO_VECTOR, ZERO_ROTATION );

Execute that in the root prim and your seat's target should be found. If you still get get seated on another prim, do the same in that one. I have made a brief script to drop in a prim and clear the sit out (presuming that no other scripts will later set it):

// KILL SIT script
default
{
state_entry ()
{
llSitTarget ( ZERO_VECTOR, ZERO_ROTATION );
llRemoveInventory ( llGetScriptName () );
}
}

NOTE: This script deletes itself, so be sure you create it in your inventory rather than inside the prim, or else leave out the line llRemoveInventory ( llGetScriptName () );

as for anims, I think there are some in the freebie bmx bike but don't quote me on that.
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
12-13-2006 10:30
Thank you so much--I think I am almost at the point of possibly understanding this.

So--all rotation is done around the root prim, and there is no "hierarchy" in a linked set. In other words, there is only one root prim in a set, and any scripts, etc that are in the other prims will not run. So I cannot put a rotation script in a secondary prim (if that's the right term), much less a former root prim in a linked set (such as the hub of a wheel).

I gather the only way to acheive wheel rotation is to use texture rotation. I think there was a recent thread on that here, I suppose I ought to read that.

As far as seats go, however, I am at a loss. If there is only one root prim which the seat target is based off, how are passengers accounted for? Why don't they all sit in the same place?

I have managed to get my bicycle working using this script--I have a no texture base as the root prim, and I adjusted argument in llSitTarget so the rider sits on the seat. Thanks to help elsewhere in this forum, the rider animation now works as well. But still no wheel rotation, and not quite sure how to create a tandem.
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
12-13-2006 10:56
From: Virrginia Tombola
...
So--all rotation is done around the root prim, and there is no "hierarchy" in a linked set. In other words, there is only one root prim in a set, and any scripts, etc that are in the other prims will not run. So I cannot put a rotation script in a secondary prim (if that's the right term), much less a former root prim in a linked set (such as the hub of a wheel).

I gather the only way to acheive wheel rotation is to use texture rotation. I think there was a recent thread on that here, I suppose I ought to read that.
...


Not quite... the other scripts do indeed run, rotation just doesn't act the same... It just rotates itself without affecting other prims. Each prim rotates around its own axis, not the root. What was probably happening was your axle was rotating alone, which would be hard to see.

From: Virrginia Tombola
...
As far as seats go, however, I am at a loss. If there is only one root prim which the seat target is based off, how are passengers accounted for? Why don't they all sit in the same place?

Any prim can be a seat prim. The root prim need not have a seat target. When sit is selected, the following happens:

If the selected prim has a sit target (via script), then the avatar is seated there.

If not, then the link hierarchy is searched for one that does, starting with the root and going up in link number.

If a prim is found with a sit target, and someone else is on it, then the system keeps looking.

If no prims are found with a sit target, then the avatar is seated 'the default way' on the selected prim, provided its geometry allows the sit to be calculated, otherwise you are told there is no room to sit.

So, to make a vehicle with a passenger seat, place a sit script in that prim, and link it in second (second to last chosen, as prim link numbers are in reverse of how they are selected, making the root the last one selected for link). You can control the link order for every prim in an object, by shift clicking, last to first, or just drag to select all, then shift click to de-select the last few you want ordered, then shift-click to re-select them down to the root and link.

Repeat for a more seats if you wish, etc (handle bars?).

If you wish to limit the number of riders, then put a script in the next prim to unseat anyone sitting on it, but make sure that prim is hard to click on (inside of another, underneath the others, etc) so riders dont accidentally click there to sit as a legitimate rider.

~Boss
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
12-13-2006 11:01
A-ha! *light bulb flickers above head*

I like the idea of putting a passenger on the handlebars, too :)
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
And the fiddling about with things continues....
12-19-2006 12:22
From: Boss Spectre
Not quite... the other scripts do indeed run, rotation just doesn't act the same... It just rotates itself without affecting other prims. Each prim rotates around its own axis, not the root. What was probably happening was your axle was rotating alone, which would be hard to see.



Hum--with that in mind I made spoke discs using alpha channels (what I should have done in the first place, really--cuts down significantly on primmage). Then I put the front wheel scripts in the frontwheel and tire, and the rear wheel in the rear wheel.

Yet, it doesn't seem to do anything. I am using the scripts from this thread. Any ideas about what to look for? It compiled without a problem.
Jolan Nolan
wannabe
Join date: 12 Feb 2006
Posts: 243
12-20-2006 02:18
You mentioned the front wheel script is in the 'wheel and tire' - Perhaps only 1 script in the tire alone?

- Jolan
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
12-20-2006 16:38
From: Jolan Nolan
You mentioned the front wheel script is in the 'wheel and tire' - Perhaps only 1 script in the tire alone?

- Jolan



*nod* I'll try that--perhaps there's some sort of interference. If so, what I'll need to do is make the tire part of the wheel prim (via a texture)

Speaking of interference, does it matter if the prim intersects another prim? My clear base has a bit of an overlap, maybe that is why the wheel won't move.
Jolan Nolan
wannabe
Join date: 12 Feb 2006
Posts: 243
12-21-2006 15:32
I shouldn't matter if the wheen touches something because in my car, when the front wheels turn, they go into the under-carrage. Here is a nice little doodle that might help :).

- Jolan
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
12-21-2006 17:42
That is correct, prim movement and rotation within the linked set is not affected by intersection with other prims in the object.
Virrginia Tombola
Equestrienne
Join date: 10 Nov 2006
Posts: 938
12-22-2006 12:38
Well, one possible reason down :P I think I'll just have to look at the script again (and again and again....)

Does the root prim matter for this? I've been using the base, not the sit (and adjusted the llSitTarget to put the avi on the seat)
1 2