- Home /
Shooting Rigidbody to a position (ballistics) creates NaN velocity errors
I have a player that throws RigidBody objects to a specific position. This position is an empty GameObject parented to the player's first-person camera, and changes position depending on where the player is looking. I have the following script, that calculates the velocity for the RigidBody perfectly if the player is looking straight ahead (as in, the empty game object is on the same y-level as the RigidBody in question). If the player looks downward, the RigidBody still is thrown at a velocity so that it hits the position. This means the target position is a few meters below the thrown RigidBody
The problem is when the player looks upwards. The ballistics script has trigonometry errors that make the velocity returned be (NaN, NaN, NaN). Why does the target position being higher than the RigidBody break my code?
public Vector3 Ballistics(Vector3 destination, float initialAngle) {
// This method is called when thrown/shot, and helps the player aim.
float gravity = Physics.gravity.magnitude;
// Selected angle in radians
float angle = initialAngle * Mathf.Deg2Rad;
// Positions of this object and the target on the same plane
Vector3 planarTarget = new Vector3(destination.x, 0, destination.z);
Vector3 planarPostion = new Vector3(transform.position.x, 0, transform.position.z);
// Planar distance between objects
float distance = Vector3.Distance(planarTarget, planarPostion);
// Distance along the y axis between objects
float yOffset = transform.position.y - destination.y;
float initialVelocity = (1 / Mathf.Cos(angle)) * Mathf.Sqrt((0.5f * gravity * Mathf.Pow(distance, 2)) / (distance * Mathf.Tan(angle) + yOffset));
Vector3 velocity = new Vector3(0, initialVelocity * Mathf.Sin(angle), initialVelocity * Mathf.Cos(angle));
// Rotate our velocity to match the direction between the two objects
float angleBetweenObjects = Vector3.Angle(Vector3.forward, planarTarget - planarPostion) * (destination.x > transform.position.x ? 1 : -1);
Vector3 finalVelocity = Quaternion.AngleAxis(angleBetweenObjects, Vector3.up) * velocity;
return finalVelocity;
}
The Vector3 destination is the empty gameobject (which is either at the same level, higher or below the RigidBody and moved forward) and an arbitrary float initialAngle, which is set between 5 degrees to 30 degrees to handle the throwing arc.
Answer by unity_ek98vnTRplGj8Q · Jul 28, 2020 at 09:46 PM
Watch for divide by zero's, like in (1 / Mathf.Cos(angle))
, although I guess this shouldn't be a problem as long as your initial angle is never 0. I think the real culprit is your Mathf.Sqrt, when your target is above you your yOffset will be negative, and you will probable be taking the square root of a negative number which will give you a NaN. I'm not sure how to correct it though because I'm not exactly sure what you are trying to accomplish in this step, and I don't know if taking the absolute value before taking the root will give you the desired result.