After a projectile is shot, some agents need to make a run for it, if we're talking about a grenade, or look at it when we're developing a sports game. In either case, it's important to predict the projectile's landing spot in order to make decisions:
Before we get into predicting the landing position, it's important to know the time left before it hits the ground (or reaches a certain position). Thus, instead of creating new behaviors, we need to update the Projectile
class.
GetLandingTime
function to compute the landing time:public float GetLandingTime (float height = 0.0f) { Vector3 position = transform.position; float time = 0.0f; float valueInt = (direction.y * direction.y) * (speed * speed); valueInt = valueInt - (Physics.gravity.y * 2 * (position.y - height)); valueInt = Mathf.Sqrt(valueInt); float valueAdd = (-direction.y) * speed; float valueSub = (-direction.y) * speed; valueAdd = (valueAdd + valueInt) / Physics.gravity.y; valueSub = (valueSub - valueInt) / Physics.gravity.y; if (float.IsNaN(valueAdd) && !float.IsNaN(valueSub)) return valueSub; else if (!float.IsNaN(valueAdd) && float.IsNaN(valueSub)) return valueAdd; else if (float.IsNaN(valueAdd) && float.IsNaN(valueSub)) return -1.0f; time = Mathf.Max(valueAdd, valueSub); return time; }
GetLandingPos
function to predict the landing spot:public Vector3 GetLandingPos (float height = 0.0f) { Vector3 landingPos = Vector3.zero; float time = GetLandingTime(); if (time < 0.0f) return landingPos; landingPos.y = height; landingPos.x = firePos.x + direction.x * speed * time; landingPos.z = firePos.z + direction.z * speed * time; return landingPos; }
First, we solve the equation from the previous recipe for a fixed height and, given the projectile's current position and speed, we are able to get the time at which the projectile will reach the given height.