Created
July 10, 2016 21:59
-
-
Save brettmjohnson/69128e9c8de0db2a9de741d8f09b951b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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