Jump to content

Arrow scripting HELP!


kira Alena
 Share

You are about to reply to a thread that has been inactive for 1358 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

So im working on some arrows, and im having massive issues changing the physics type in time to get it to "stick" into the collided object. The arrows bounce for a few seconds after it collides, even though I have the status changing to false right as is collides. Anyone know a workaround?!

 

Gif for reference: https://gyazo.com/936089f82927c5d5f09c804dfb9546c2

Link to comment
Share on other sites

12 hours ago, kira Alena said:

So im working on some arrows, and im having massive issues changing the physics type in time to get it to "stick" into the collided object. The arrows bounce for a few seconds after it collides, even though I have the status changing to false right as is collides. Anyone know a workaround?!

 

Gif for reference: https://gyazo.com/936089f82927c5d5f09c804dfb9546c2

This is always a problem because the arrow is travelling for some frames before the simulator registers that it's hit the target, sets it to non-physical, and gets the information to your computer about where the arrow is supposed to be when it stops.    It's the same bug in the physics system that allows "wallwalkers" to blast you through solid walls, by calling llMoveToTarget to move you so quickly that that the simulator doesn't realise there's a wall in the way before you're though it.

You ask for suggestions for a workaround.  I'd start by lowering the projectile's velocity, to see if that helps -- the slower it's travelling, the better your chance of halting it somewhere near the right place.   

If that doesn't work, I'd experiment with trying to rez a second, non-physical, arrow in place, where you hit the target.    I think the way I'd do this is have the arrow do a ray cast as soon as it rezzes, to detect what it's going to hit, and then rez a copy of itself at the predicted impact point (you might need to delay rezzing the second arrow by a frame or two -- that you'd have to experiment with).     That's how I'd start, anyway.

Link to comment
Share on other sites

40 minutes ago, Innula Zenovka said:

This is always a problem because the arrow is travelling for some frames before the simulator registers that it's hit the target, sets it to non-physical, and gets the information to your computer about where the arrow is supposed to be when it stops.    It's the same bug in the physics system that allows "wallwalkers" to blast you through solid walls, by calling llMoveToTarget to move you so quickly that that the simulator doesn't realise there's a wall in the way before you're though it.

There's a couple technical details wrong here that I'd like to clarify:

  • Second Life doesn't have "continuous physics." This means that physics are checked distinctly (discreetly?) frame-by-frame for collisions.
    • If a wall is 1 meter thick and you have a 1 meter cube moving at 100 meters per second, collisions will only be checked once every 2.222 meters.
    • This means that a cube may "skip past" the wall with no detectable collision as far as the physics system is concerned. If the cubes didn't touch during a frame, they didn't collide. (This is why bullets meant for combat tend to be several meters long, about 5 meters on average.)
    • It's not that the projectile is too fast, it's just that the sim doesn't take speed into account to predict a collision that is about to happen before the next frame.
  • Your computer isn't responsible for anything script- or physics-related in the world. All physics, even your avatar movement, is entirely controlled by the sim.
    • What your computer does is linearly interpolate (as in, displays a prediction of) movement. The sim tells you "this object was here with this velocity" and your viewer will display the object moving with that velocity (forever, even through objects) until the sim tells you a new position/velocity.
    • The video of the arrow stopping and falling to the ground happens because the sim detects a collision and sets the velocity to zero. Then gravity takes over and it falls to the ground. If the script (which exists on the sim where the physics are happening) doesn't get its timeslice to stop the arrow, there are only a few things you can do.

A couple desperate solutions would be:

  • Add an invisible prim (longer than velocity/45.0) around the arrow, perhaps so that the visible arrow is near the tip of the prim.
  • Remove gravity (and lock rotation) from the object, so that it can stay in the air instead of dropping onto the ground after a collision.
  • Use raycast to detect surfaces in front of the projectile while it's in flight and use that to better approximate your collisions.
  • Use llDetectedKey, llCastRay, and some guesstimating to figure out what was hit in the collision event, regardless of how long ago the collision happened.
Edited by Wulfie Reanimator
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

3 minutes ago, Wulfie Reanimator said:

Remove gravity (and lock rotation) from the object, so that it can stay in the air instead of dropping onto the ground after a collision.

Thanks for the clarification about what's happening server-side.   But how does removing gravity and locking rotation work better than setting STATUS_PHYSICS to FALSE, which I think is what the OP is doing anyway and finding it doesn't stop the arrow quickly enough?  

Since the problem involves a delay between the arrow hitting something and the simulator doing something about it, I think the solution is going to be to anticipate what the projectile will hit, and where, and then plan to stop it when it arrives there (or rez a new instance there at the right time) but I think only experiment will show the best way to do this.   

Link to comment
Share on other sites

2 minutes ago, Innula Zenovka said:

Thanks for the clarification about what's happening server-side.   But how does removing gravity and locking rotation work better than setting STATUS_PHYSICS to FALSE, which I think is what the OP is doing anyway and finding it doesn't stop the arrow quickly enough?  

Since the problem involves a delay between the arrow hitting something and the simulator doing something about it, I think the solution is going to be to anticipate what the projectile will hit, and where, and then plan to stop it when it arrives there (or rez a new instance there at the right time) but I think only experiment will show the best way to do this.  

Removing gravity will prevent the arrow from falling to the ground (as we saw) after the sim detects a collision and sets the arrow's velocity to zero.

Of course, you still need the script to "wake up" and actually remove physics completely, otherwise any bump will make the arrow float away. It's not a replacement, it's a stop-gap.

And to be more pedantic, the problem isn't that the collision happens and the sim fails to do something about it -- clearly it does, since the arrow stops against the wall -- the problem is that the script doesn't get to react reasonably fast.

Link to comment
Share on other sites

29 minutes ago, Wulfie Reanimator said:

Removing gravity will prevent the arrow from falling to the ground (as we saw) after the sim detects a collision and sets the arrow's velocity to zero.

Of course, you still need the script to "wake up" and actually remove physics completely, otherwise any bump will make the arrow float away. It's not a replacement, it's a stop-gap.

And to be more pedantic, the problem isn't that the collision happens and the sim fails to do something about it -- clearly it does, since the arrow stops against the wall -- the problem is that the script doesn't get to react reasonably fast.

Oh, I see.  Remove gravity before the arrow hits anything, and turn off physics when it does, and if it doesn't  hit anything (e.g. you fire it straight up in the air)  it simply carries on moving until it runs out of energy and stops in mid air?

Link to comment
Share on other sites

16 minutes ago, Innula Zenovka said:

Oh, I see.  Remove gravity before the arrow hits anything, and turn off physics when it does, and if it doesn't  hit anything (e.g. you fire it straight up in the air)  it simply carries on moving until it runs out of energy and stops in mid air?

Yup. That's generally how I've handled bullets anyway. Sometimes you can't do it, for example a simple ball that should have an arc to it.

Except physical objects don't "run out of energy" by just moving, a projectile with no gravity will keep its velocity forever. Generally speaking, the worst-case for a projectile is that it hits a sim border or dies by a timer/temporary status.

I'll also use llSetStatus with STATUS_ROTATE_* to prevent any wild spinning caused by collisions.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

Sorry for the late replies! So I ran a lot of tests and realized that the issue was that the script of the rezzed object had around 3 seconds of a delay before anything in the script even worked. So basically I cant do anything instantaneously until LL fixes this issue. I made a little workaround where the arrow is rezzed in front of the avatar as non-physical, and while the animation to shoot the arrow is playing, the script of the arrow "wakes up". By the time the animation is ready to shoot the arrow, the script is ready, and I set it physical and apply an impulse instead of rezzing with velocity. Unfortunately this is all I can do until LL fixes the issue.

Link to comment
Share on other sites

1 hour ago, Wulfie Reanimator said:

Yup. That's generally how I've handled bullets anyway. Sometimes you can't do it, for example a simple ball that should have an arc to it.

Except physical objects don't "run out of energy" by just moving, a projectile with no gravity will keep its velocity forever. Generally speaking, the worst-case for a projectile is that it hits a sim border or dies by a timer/temporary status.

I'll also use llSetStatus with STATUS_ROTATE_* to prevent any wild spinning caused by collisions.

For a projectile, though, I normally leave gravity alone (unless there's a good reason to change it) and handle what should happen in a collision event, since it's bound to collide with something sooner or later (and if it doesn't, it's temp on rez anyway, so it won't hang around long).   

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1358 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...