Skip to content

Instantly share code, notes, and snippets.

@brettmjohnson
Created July 10, 2016 21:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brettmjohnson/69128e9c8de0db2a9de741d8f09b951b to your computer and use it in GitHub Desktop.
Save brettmjohnson/69128e9c8de0db2a9de741d8f09b951b to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
public class TrajectoryCalculation : MonoBehaviour
{
public Rigidbody projectile;
public Transform target;
[Header("CalculateBestThrowSpeed")]
public float timeToTarget = 1f;
[Header("CalculateTrajectory")]
public float speed = 10;
[Range(0, 1)] public float arc = 0;
void Update()
{
if (Input.GetKeyDown("a"))
{
GameObject p = Instantiate(projectile, transform.position, transform.rotation) as GameObject;
p.GetComponent<Rigidbody>().AddForce(CalculateBestThrowSpeed(transform.position, target.position, timeToTarget), ForceMode.VelocityChange);
Destroy(p, 10);
}
if (Input.GetKeyDown("b"))
{
Vector3 velocity;
if (CalculateTrajectory(transform.position, target.position, speed, out velocity, arc))
{
GameObject p = Instantiate(projectile, transform.position, transform.rotation) as GameObject;
p.GetComponent<Rigidbody>().AddForce(velocity, ForceMode.VelocityChange);
Destroy(p, 10);
}
else
{
Debug.Log("Target cannot be reached. Increase speed or reduce distance.");
}
}
}
// from http://answers.unity3d.com/answers/456066/view.html
static Vector3 CalculateBestThrowSpeed(Vector3 origin, Vector3 target, float timeToTarget)
{
Vector3 toTarget = target - origin;
Vector3 toTargetXZ = toTarget;
toTargetXZ.y = 0;
float y = toTarget.y;
float xz = toTargetXZ.magnitude;
float v0y = y / timeToTarget + 0.5f * Physics.gravity.magnitude * timeToTarget;
float v0xz = xz / timeToTarget;
Vector3 result = toTargetXZ.normalized;
result *= v0xz;
result.y = v0y;
return result;
}
// based on http://gamedev.stackexchange.com/questions/114522/how-can-i-launch-a-gameobject-at-a-target-if-i-am-given-everything-except-for-it/114547
static bool CalculateTrajectory(Vector3 origin, Vector3 target, float speed, out Vector3 velocity, float arc = 0f)
{
Vector3 toTarget = target - origin;
Vector3 toTargetXZ = toTarget;
toTargetXZ.y = 0;
float y = toTarget.y;
float xz = toTargetXZ.magnitude;
float gravity = Physics.gravity.magnitude;
float b = speed*speed - y * gravity;
float discriminant = b * b - gravity * gravity * (xz * xz + y * y);
if (discriminant < 0) // out of range, need higher shot speed
{
velocity = Vector3.zero;
return false;
}
float discRoot = Mathf.Sqrt(discriminant);
float minTime = Mathf.Sqrt((b - discRoot) * 2) / Mathf.Abs(gravity); // impact time for the most direct shot that hits
float maxTime = Mathf.Sqrt((b + discRoot) * 2) / Mathf.Abs(gravity); // impact time for the highest shot that hits
float time = (maxTime - minTime) * arc + minTime;
float v0xz = xz / time;
float v0y = y / time + time * gravity / 2;
velocity = toTargetXZ.normalized;
velocity *= v0xz;
velocity.y = v0y;
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment