Help with a Thrown spear script
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-05-2008 13:41
Hey I have a weapon that I am working on that is driving me crazy. It's a thrown spear. I have gotten it to rez and attack the target correctly but as I rotate myself to aim at different targets my spear goes from being nice and straight flying to flying sideways. First with the spear butt to the right then to the left as I rotate to face new targets. Also I notice a vertical skew as well (butt of spear up). What is the easiest way to make sure the spear flys straight no matter what rotation I throw it at? Here is a sample of the code I am using to set the angle of flight:
rot = llGetRot(); // Get current region rotation of the weapon fwd = llRot2Fwd(rot); // Initialize the foward motion vector pos = llGetPos(); // Get current region position of the weapon pos = pos + fwd; // Adjust position for forward facing vector pos.x += .75; // Correct to eye point pos.z += 1.1; // Correct to eye point rot.x += 1; // Correct Rez rotation on the x axis rot.y += 0; // Correct Rez rotation on the y axis rot.z += 0; // Correct Rez rotation on the z axis
fwd = fwd * speed; // Set the forward vector fot he desired projectile speed // ... Play sounds and throw animation here llRezObject("Pilum", pos, fwd, rot, 1); // Rez and throw spear
// ... Continue with the script
Thanx in advance!
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
10-05-2008 16:40
Look for one of the freebie guns that shoot bullets. Your problem should be very similar.
_____________________
So many monkeys, so little Shakespeare.
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-05-2008 17:13
Unfortunately my freebie gun scripts don't hold the answer. I have already looked there. If you have one that does give the answer then please be forthcoming. I believe the reason for the bullets scripts not being helpful is that bullets are rarely 2 meters long and fired at a lowvelocity (like that you get from a person throwing the projectile). For most of the freebie scripts I have for guns .. the projectile shape and rotation is irrelevant since the bullet is small, symmetrical, invisible and/or the velocity is great.
|
|
Lightwave Valkyrie
Registered User
Join date: 30 Jan 2004
Posts: 666
|
10-05-2008 22:01
try the free linden bow and arrow scripts just north of morris sim
_____________________
L$ is the root of all evil videos work! thanks SL 
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-06-2008 07:04
Thanx Ill look there and give feedback of the success or failure of my attempts.
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-06-2008 15:48
OK .. I'm sorry .. but I have searched all through Morris SIM I found an archery range but no place to get bow and arrow scripts. Can you give me a more precise location or post them here?
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
10-06-2008 15:52
While you are searching for the bow and arrow script, can you provide a little more data about your spear?
Is there a target (like a vector)? Is it there a direction and elevation angle and initial force? For that matter, is the spear physical? have you considered making it a vehicle?
My other work is out of the way for now, and I thought I might fool around with the spear idea.
_____________________
So many monkeys, so little Shakespeare.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-06-2008 16:15
EDIT: This post self deleted!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-06-2008 16:17
Lee,
The spear is a multi-prim object with a hit detect and damage script in it. The root prim in the handle of the spear roughly in the center of mass of the object. The spear is rezzed, physical, like an arrow pointing toward the target simply by being aligned with the facing of the avatar throwing it.
Upon throwing (clicking the mouse button), the code sample I gave is executed getting the geometry of the object and then rezzing the object using:
llRezObject("Pilum", pos, fwd, rot, 1); // Rez and throw spear
Where pos- is the starting position adjusted for 'eye' level, fwd - is the velocity vector that the spear will be given rot - is the rotation the weapon will have when rezzed
The Rot is the problem. I cannot seem to get it right. The weapon is targeted fine .. and hits the target true but it is always canted left or right when thrown in all but one direction.
Does this help?
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-06-2008 16:24
Well it does state that the author is Linden Labs so here goes, instead of people having to go to a known greifers page. Hope it helps: Assembly Make cube Put bow script in cube Name Cube bow Make a long, thin cylinder or something Name it Arrow Make it physical Take arrow and put it in bow. Take bow and put it on your HUD somewhere. BOW SCRIPT // // Bow Script // // This script is a bow - it waits for a mouseclick in mouselook and // then fires an arrow in the direction the user is facing. // It also animates the avatar holding it, to create a convining hold and // firing look for the bow. // // This script can be used as a good basis for other weapons. Change // the animations to others for guns, etc. // float SPEED = 30.0; // Speed of arrow in meters/sec integer LIFETIME = 10; // How many seconds will arrows live // before deleting themselves float DELAY = 2.0; // Delay between shots to impose vector vel; // Used to store velocity of arrow to be shot vector pos; // Used to store position of arrow to be shot rotation rot; // Used to store rotation of arrow to be shot integer have_permissions = FALSE; // Indicates whether wearer has yet given permission // to take over their controls and animation. integer armed = TRUE; // Used to impose a short delay between firings string instruction_held_1 = "Use Mouselook (press 'M') to shoot me."; string instruction_held_2 = "Choose 'Detach' from my menu to take me off."; // Echoed to wearer when they are holding the bow string instruction_not_held = "Choose 'Acquire->attach->left hand' from my menu to wear and use me."; // Echoed to toucher if not worn fire() { // // This subroutine creates and fires an arrow // if (armed) { // // Actually fires the arrow // armed = FALSE; rot = llGetRot(); // Get current avatar mouselook direction vel = llRot2Fwd(rot); // Convert rotation to a direction vector pos = llGetPos(); // Get position of avatar to create arrow pos = pos + vel; // Create arrow slightly in direction of travel pos.z += 0.75; // Correct creation point upward to eye point // from hips, so that in mouselook we see arrow // travelling away from the camera. vel = vel * SPEED; // Multiply normalized vector by speed llStartAnimation("shoot_L_bow"); // Trigger the bow release animation llTriggerSound("bow_release", 1.0); // Make the sound of the arrow being shot llRezObject("arrow", pos, vel, rot, LIFETIME); // Create the actual arrow from object // inventory, and set its position, velocity, // and rotation. Pass a parameter to it to // tell it how long to live. llSetTimerEvent(DELAY); // Wait until can fire again } } default { state_entry() // // This routine is called whenever the script is edited and restarted. So if you // are editing the bow while wearing it, this code will re-request permissions // to animate and capture controls. // { if (!have_permissions) { llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS); } } run_time_permissions(integer permissions) { // // This routine is called when the user accepts the permissions request // (sometimes this is automatic) // so on receiving permissions, start animation and take controls. // if (permissions == PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS) { llWhisper(0, instruction_held_1); llWhisper(0, instruction_held_2); llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE); llStartAnimation("hold_L_bow"); have_permissions = TRUE; } } attach(key attachedAgent) { // // If attached/detached from agent, change behavior // if (attachedAgent != NULL_KEY) { // Bow has been attached or rezzed from inventory, so // ask for needed permissions. llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS); } else { // Bow has been detached from avatar, so stop animation and release controls if (have_permissions) { llStopAnimation("hold_L_bow"); llReleaseControls(); llSetRot(<0,0,0,1>); have_permissions = FALSE; } } } control(key name, integer levels, integer edges) { // This function is called when the mouse button or other controls // are pressed, and the controls are being captured. // // Note the logical AND (single &) used - the levels and edges // variables passed in are bitmasks, and must be checked with // logical compare. // // Checking for both edge and level means that the button has just // been pushed down, which is when we want to fire the arrow! // if ( ((edges & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON) &&((levels & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON) ) { // If left mousebutton is pressed, fire arrow fire(); } } touch_end(integer num) { // If touched, remind user how to enter mouselook and shoot if (have_permissions) { llWhisper(0, instruction_held_1); llWhisper(0, instruction_held_2); } else { llWhisper(0, instruction_not_held); } } timer() { // After timer expires, allow user to shoot bow again llSetTimerEvent(0.0); armed = TRUE; } } ARROW SCRIPT: // // Arrow Script // // This is a basic script for an arrow shot from a bow // The arrow is created and shot, gets a lifetime passed as a // parameter (after which it deletes itself), and has adjustable levels // of damage (how much it hurts another avatar if it hits them). // float DAMAGE = 25.0; // How much to hurt a struck avatar // This will only affect them on healh-enabled land, // set to zero for no harm. default { state_entry() { llSetDamage(DAMAGE); llPassCollisions(TRUE); llSetStatus(STATUS_PHYSICS, TRUE); llSetStatus(STATUS_PHANTOM, FALSE); } collision_start(integer detected) { // // This routine is called when the arrow collides with another avatar or an // object. // llSetStatus(STATUS_PHYSICS, FALSE); // Freeze arrow where it hit. llTriggerSound("impact_2", 1.0); // Play an impact sound. llSetStatus(STATUS_PHANTOM, TRUE); // Make arrow non-colliding. } on_rez(integer param) { // // When the arrow is created, set a timer to expire if a non-zero parameter // is passed. If the arrow is rezzed from inventory (as with editing), this // timer event will not be set and the arrow will never die. // if (param > 0) { llSetTimerEvent((float)param); } } timer() { // After the lifetime passed in on creation, delete the arrow. llDie(); } land_collision_start(vector pos) { // If land is collided with, delete the arrow immediately. llTriggerSound("impact_3", 1.0); // Play an impact sound. llDie(); } }
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-06-2008 16:32
Jesse,
With the exception of the names my geometry calls are identical So this makes it more confusing .. It does not seem that I am doing anything different. The scripts I am basing my work off of must have originally come from the Linden Labs code. I am wondering if the problems is that I have a multi-prim spear?
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-06-2008 16:39
From: Gwillym Wycliffe Jesse,
With the exception of the names my geometry calls are identical So this makes it more confusing .. It does not seem that I am doing anything different. The scripts I am basing my work off of must have originally come from the Linden Labs code. I am wondering if the problems is that I have a multi-prim spear? Weapons have never been of interest to me so there are definitely people who could answer your questions better. Lee would definitely be one and Ordinal Malaprop comes to mind also. But basics of debugging I know something about. Try changing your spear to a simple cylinder and see how it reacts?
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
10-06-2008 17:54
From: Gwillym Wycliffe ...The root prim in the handle of the spear roughly in the center of mass of the object. The spear is rezzed, physical, like an arrow pointing toward the target simply by being aligned with the facing of the avatar throwing it. That last sounds like a telling bit to me. The spear's rotation when rezzed should be calculated relative to the avatar's rotation. Here's what I would recommend: face your avatar due East (that's actually the equivalent of ZERO_ROTATION for an avatar, since the avatar's x-axis points straight forward and the world's x-axis points straight to the East). Put the spear in front of you and orient it in the direction you think it should face were you to throw it (rez it) in that position. Then have it print out the result of llGetRot(). Something like: default { touch_start(integer nDetected) { llOwnerSay("My rotation is: "+(string)llGetRot()); } }
Let's say it just happens to look something like: My rotation is <0.000000, 0.707107, 0.000000, 0.707107> We can call that its relative rez rotation and put it at the top of our script that rezzes the spear. Something like: rotation RELATIVE_REZ_ROT = <0.0, 0.707107, 0.0, 0.707107>;
Now we have to take that rotation, which is in the avatar's coordinate system ("relative" to the avatar) and translate it into the global coordinate system. The way to do that is to multiply (transform) the relative orientation by whatever the current rotation of the avatar is. From an attachment, llGetRot() returns the rotation of the avatar. So our rezzing script should now look something like: rotation RELATIVE_REZ_ROT = <0.0, 0.707107, 0.0, 0.707107>; ... rotation avatarRot = llGetRot(); rotation globalSpearRot = RELATIVE_REZ_ROT*avatarRot; llRezAtRoot(SPEAR_NAME, globalSpearPos, globalSpearVelocity, globalSpearRot, rezParam); // Feel free to use llRezObject() instead of llRezAtRoot() if you really want to ...
As it turns out, the avatar's rotation is also very helpful in calculating a position and velocity relative to the avatar. That's because an avatar's (or object's) rotation is really a transformation between a vector (length and direction) in the avatar's (object's) local coordinate system and the global coordinate system. I assume you probably want to rez the spear a short ways in front of the avatar; that's in the avatar's local x direction. That way the thrower won't impale him/herself right off the bat. Maybe you want to offset it in the local z direction a bit too so it's a little over head height or so rather than at the avatar's midsection (about belly button height). So let's say 3m in front of the avatar and 1.5m above its midpoint. Most likely you'll want the spear to travel forward (avatar's +x direction) too. Maybe you'll want to throw it upward a bit to give it a nice trajectory, but I'll just use a forward vector for this example. Let's pick an arbitrary 10 meters per second. That sounds fair. rotation RELATIVE_REZ_ROT = <0.0, 0.707107, 0.0, 0.707107>; vector RELATIVE_REZ_POS = <3.0, 0.0, 1.5>; // 3m forward, 1.5m up vector RELATIVE_REZ_VELOCITY = <10.0, 0.0, 0.0>; // 10m/s straight forward ... rotation avatarRot = llGetRot(); rotation globalSpearRot = RELATIVE_REZ_ROT*avatarRot; vector globalSpearVelocity = RELATIVE_REZ_VELOCITY*avatarRot; vector avatarPos = llGetPos(); vector globalSpearPos = avatarPos+RELATIVE_REZ_POS*avatarRot; llRezAtRoot(SPEAR_NAME, globalSpearPos, globalSpearVelocity, globalSpearRot, rezParam); // Feel free to use llRezObject() instead of llRezAtRoot() if you really want to
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
10-06-2008 18:22
Jesse,
I changed the spear to a 2m cylinder 0.05 M in diameter and had the same result as withthe multi-prim spear.
Hewee,
I am pouring over your post now. I will try your approach and see how it works. Just reading it over several times I have learned several things. Ill test and post when I have some results to report.
Thanx!
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
For what it is worth...
10-06-2008 20:13
float factor=10;
default {
touch_start(integer total_number) { rotation r = llGetRot(); vector p = llGetPos() + <0,-.3,1>*r; vector v = (factor*<1,0,.5>)*r; llRezObject("spear", p, v, r, 1); } } [\PHP]
I made a box, and put this script in it. I wear the box on my head (or nose, ear, one of those head related body parts). The rotation of the box is X is the same as my X.
Then, I made a spear using a TUBE (not a cylinder). X on a cylinder is out one of the sides. X on a tube is along the tubiness. If you use a cylinder, you might have to adjust for Z being FWD.
Put the spear in the box with the script.
Good news: When I touch the box, it shoots a spear in the correct direction.
Strange news: Every once in awhile, the spear shoots out sideways, sort of like Gwilym is reporting.
Good luck.
_____________________
So many monkeys, so little Shakespeare.
|
|
Gwillym Wycliffe
Registered User
Join date: 9 Mar 2008
Posts: 8
|
11-24-2008 13:30
Hewee et all. So for taking so long to post a reply. I am easily distracted and get lost on wide tangents. I used your example even down to setting the reference rotation to your example of "RELATIVE_REZ_ROT = <0.000000, 0.707107, 0.000000, 0.707107>" and over all it works!!! There is some rotatonal drift, but I figure I can get rid of that by refining what I use for "RELATIVE_REZ_ROT". I just need to put the focus and time in to resolve it.
Lee .. I also like the idea of using the TUBE instead of the cylinder. I think that between these two things the problem will be licked.
Thank you Everyone!!!! Gwill
|