Okay, so the first thing to bear in mind is that the goal to solving this is to treat the object's motion along the two axes separately, which we'll call x and y. Although the results of this can be used in 3d space, this problem only concerns two axes, which is nice. Our given values (the ones we have) are the position of our object, position of the target, and the angle that we want to fire at. From this, we know the planar distance between the object (d) as well as the offset on the y axis between the two. We want the initial velocity to fire the object at to strike the target t.
As stated above, we'll find the velocity of the components, x and y. vX (velocity x) is constant (there's no air resistance or anything) and so is the following:
Code (csharp):
- v0 * cos(angle)
vY is just as easy to solve for, giving us:
Code (csharp):
- v0 * sin(angle)
Code (csharp):
- vY = -gt + v0 * sin(angle)
Code (csharp):
- -1/2*g*t^2 + v0 * sin(angle)*t + y0
Code (csharp):
- v0 = (1 / Mathf.Cos(angle)) * Mathf.Sqrt((0.5f * gravity * Mathf.Pow(distance, 2)) / (distance * Mathf.Tan(angle) + yOffset));
Code (csharp):
- using UnityEngine;
- using System.Collections;
- public class ProjectileFire : MonoBehaviour {
- [SerializeField]
- Transform target;
- [SerializeField]
- float initialAngle;
- void Start () {
- var rigid = GetComponent<Rigidbody>();
- Vector3 p = target.position;
- 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
- // Planar distance between objects
- float distance = Vector3.Distance(planarTarget, planarPostion);
- // Distance along the y axis between objects
- float yOffset = transform.position.y - p.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);
- Vector3 finalVelocity = Quaternion.AngleAxis(angleBetweenObjects, Vector3.up) * velocity;
- // Fire!
- rigid.velocity = finalVelocity;
- // Alternative way:
- // rigid.AddForce(finalVelocity * rigid.mass, ForceMode.Impulse);
- }
- }
No comments:
Post a Comment