- Home /
How to make an arrow fly realistically.
Hey guys! Now I've seen a bunch of other questions and topics like this on the forums, but none of them work for what I am needing. Basically I wan't an arrow that is shot from a bow to move realistically (The tip of the arrow points in the way it's traveling.) but I can only find code that works for an only-right bow. Here's a picture of what I'm talking about:
And here's the code I'm using: EDIT: Do NOT use LerpAngle for functions like this. It makes the Rotation go from 360 degrees back to 0 instead of rotating it properly.
Vector3 velocity = rigidbody2d.velocity;
float angle = Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg;
Quaternion tempRotation = Quaternion.AngleAxis(angle, Vector3.forward);
Quaternion newRotation = gameobejct.transform.rotation;
newRotation.x = Mathf.LerpAngle(newRotation.x, tempRotation.x, speed);
newRotation.y = Mathf.LerpAngle(newRotation.y, tempRotation.y, speed);
newRotation.z = Mathf.LerpAngle(newRotation.z, tempRotation.z, speed);
newRotation.w = Mathf.LerpAngle(newRotation.w, tempRotation.w, speed);
Thanks!
1) Are you using this code in Update or FixedUpdate?
2) How does this change the objects trajectory? I don't see where you are assigning any of these values back to the rigidbody or object.
To simulate an arrow it should be enough to just simulate gravity. For instance something like
void FixedUpdate(){
rigidbody2d.velocity+=gravity*Vector3.down;
transfrom.rotation=Quaternion.LookRotation(rigidbody2d.velocity);
}
The code is being called in FixedUpdate, and it only changes how fast the arrow rotates depending on where I place the code. Also, I made the code a function that can be called so it's returning the Quaternion, not modifying it. Another thing, the code you gave me is very weird... What is the "gravity" variable and why would I be modifying the velocity of the arrow? I already have a rigidbody2d on the arrow, I don't need to simulate gravity twice. Also, i'f I just use the
transfrom.rotation=Quaternion.LookRotation(rigidbody2d.velocity);
code, it makes my arrow disappear after I shoot it.
The variable gravity would be a float that represents the acceleration felt due to gravity. For instance, in real life gravity would by 9.8 m/s^2. I assumed that you would be modifying the velocity of the arrow is because this is what happens in real life and what gives arrows a parabolic trajectory.
http://www.physicsclassroom.com/class/vectors/Lesson-2/Characteristics-of-a-Projectile-s-Trajectory
Of course, this is a video game and you are free to make your own physics.
transfrom.rotation=Quaternion.LookRotation(rigidbody2d.velocity);
is just supposed to look in the direction the arrow is traveling and is probably disappearing because the arrows forward is not the same same the arrows object forward or the world up is not the same as the direction you want the arrows up to be aligned with. Since this is 2D you can probably just use $$anonymous$$athf.Atan2 to get the rotation along the z axis.
Alright, thanks. I've found a solution that works:
Vector2 velocity = rigidbody2d.velocity;
float angle = $$anonymous$$athf.Atan2(velocity.y, velocity.x) * $$anonymous$$athf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
I just make sure that the arrow is facing right at (0, 0, 0) and place the code in Update.
Answer by NinjaISV · Jun 30, 2015 at 12:49 AM
Uhuh! I've found a solution that works perfectly! I did a little more research and found this: http://answers.unity3d.com/questions/757118/rotate-towards-velocity-2d.html
Basically this code should work if your arrow is facing right at the rotation (0, 0, 0,).
Vector2 v = rigidbody2D.velocity;
angle = Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
it's works but why the arrow still rotate when he fall in the ground (sorry about my language) help me plz i trying to make a 2d game like tower fall and thank you
This only points the arrow in the direction of the rigidbody2D velocity vector. If it is spinning it is something you are doing.
Wow! Great find, NinjaISV. This worked perfect for me!
For anyone who has a projectile at a different orientation than desired, merely multiply the projectile's quaternion by the degrees you want to rotate it by.
Vector3 velocity = GetComponent().velocity;
float angle = $$anonymous$$athf.Atan2(velocity.y, velocity.x) * $$anonymous$$athf.Rad2Deg;
Quaternion myRotation = Quaternion.AngleAxis(angle, Vector3.forward) * Quaternion.Euler(0, 0, -90); // <- I needed to change my launch by 90 degrees
transform.rotation = myRotation;
Answer by Hellium · Jun 29, 2015 at 06:49 PM
Manipulating the values of quaterions individually is a very, very, very, very, very bad idea, unless you perfectly know what you are doing (and it's not the case obviously).
Unity has a built-il method to do a Slerp between two quaternions simply called Quaternion.Lerp http://docs.unity3d.com/ScriptReference/Quaternion.Lerp.html
Ahhh. That must have been one of the mistakes I made. Thanks.
How would you assess the 2nd Quaternion in the case of an arrow shot towards an unknown object? Thanks for the help!
You mean like make the arrow point at a target ins$$anonymous$$d of the direction it is traveling? This would look very unrealistic and messy. I advise you just add the appropriate amount of force to the arrow to make it travel towards the target, thus making it face the target and travel towards it.
Answer by gloton2535 · Mar 09, 2019 at 02:36 AM
https://answers.unity.com/questions/14899/realistic-rotation-of-flying-arrow.html maybe could more help