平拋運動:
1.物體以一定的初速度水平方向拋出,如果物體僅受重力作用,這樣的運動叫做平拋運動。
2.平拋運動可看作水平方向的勻速直線運動以及豎直方向的自由落體運動的合運動。
水平方向位移:s = v * t
豎直方向位移:h = 1/2 * g * t * t
3.平拋物體的運動軌跡為拋物線。

HorizontalThrow.cs
1 using System; 2 using UnityEngine; 3 4 public class HorizontalThrow : MonoBehaviour { 5 6 private readonly float gravity = -9.8f; //重力加速度 7 private Vector2 horizontalDir; //水平方向 8 private float horizontalSpeed; //水平速度 9 private Vector3 startPos; //開始位置 10 private float endY; //結束高度(地面高度) 11 private float timer; //運動消耗時間 12 private Action<GameObject> finishCallBack; //落地后的回調 13 private bool canMove = false; //能否運動 14 15 void Update () 16 { 17 if (!canMove) 18 { 19 return; 20 } 21 22 //移動過程 23 timer = timer + Time.deltaTime; 24 25 float xOffset = horizontalSpeed * horizontalDir.x * timer; 26 float zOffset = horizontalSpeed * horizontalDir.y * timer; 27 float yOffset = 0.5f * gravity * timer * timer; 28 29 Vector3 endPos = startPos + new Vector3(xOffset, yOffset, zOffset); 30 if (endPos.y < endY) 31 { 32 endPos.y = endY; 33 canMove = false; 34 } 35 transform.position = endPos; 36 37 //移動結束 38 if (!canMove) 39 { 40 finishCallBack(gameObject); 41 Destroy(this); 42 } 43 } 44 45 public void StartMove(Vector2 horizontalDir, float horizontalSpeed, float endY, Action<GameObject> finishCallBack) 46 { 47 this.horizontalDir = horizontalDir; 48 this.horizontalSpeed = horizontalSpeed; 49 startPos = transform.position; 50 this.endY = endY; 51 timer = 0; 52 this.finishCallBack = finishCallBack; 53 canMove = true; 54 } 55 }
TestHorizontalThrow.cs
1 using UnityEngine; 2 using System.Collections.Generic; 3 4 public class TestHorizontalThrow : MonoBehaviour { 5 6 public GameObject testGo; 7 private bool isDebug = false; 8 private List<GameObject> drawGoList = new List<GameObject>(); 9 10 void Update () 11 { 12 if (Input.GetKeyDown(KeyCode.Q)) 13 { 14 //半徑為1的方向圓 15 float randomNum = Random.Range(0f, 1f);//[0, 1] 16 float x = randomNum * 2 - 1;//[-1, 1] 17 float z = Mathf.Sqrt(1 - x * x); 18 if (Random.Range(0f, 1f) > 0.5f) 19 { 20 z = -z; 21 } 22 23 isDebug = true; 24 HorizontalThrow horizontalThrow = testGo.AddComponent<HorizontalThrow>(); 25 horizontalThrow.StartMove(new Vector2(x, z), 3f, 0f, (go) => { 26 isDebug = false; 27 Debug.Log("移動結束"); 28 }); 29 } 30 else if(Input.GetKeyDown(KeyCode.W)) 31 { 32 testGo.transform.position = new Vector3(0f, 5f, 0f); 33 for (int i = 0; i < drawGoList.Count; i++) 34 { 35 Destroy(drawGoList[i]); 36 } 37 drawGoList.Clear(); 38 } 39 40 if (isDebug) 41 { 42 GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere); 43 go.transform.position = testGo.transform.position; 44 go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); 45 drawGoList.Add(go); 46 } 47 } 48 }
效果如下:

