lyh916

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

之前的斜抛运动,如果运动到游戏中,显然是太呆板了,那么可以试着加入一些效果,让它看起来更生动一些,类似游戏中的击飞或者掉落效果:

1.在达到最高点的时间点±X的时间段内,会有“减速”效果,形成一种在空中停留的感觉

2.落地后,反弹一次,再落地,就像是与地面发生了碰撞

 

相关公式:

 

ObliqueThrow.cs

  1 using System;
  2 using UnityEngine;
  3 
  4 public class ObliqueThrow : MonoBehaviour {
  5 
  6     private float gravity;                      //重力加速度(当前)
  7     private float gravityValue = -9.8f;         //重力加速度值1
  8     private Vector2 horizontalDir;              //水平方向
  9     private float startSpeed;                   //初速度
 10     private float sinValue;                     //sin值
 11     private float cosValue;                     //cos值
 12     private Vector3 startPos;                   //开始位置
 13     private float endY;                         //结束高度(地面高度)
 14     private float timer;                        //运动消耗时间
 15     private Action<GameObject> finishCallBack;  //落地后的回调
 16     private bool canMove = false;               //能否运动
 17 
 18     private float timeScale = 1;                //时间系数
 19     private float reboundTimes = 1;             //反弹次数
 20     private bool isInRebound = false;           //是否在反弹中
 21     private float lastX;                        //落地点x
 22     private float lastZ;                        //落地点z
 23     private float hightestPointTime;            //到达最高点所用的时间
 24     private float hightestPointStayTime = 0.1f; //最高点减速范围的时间段
 25 
 26     void Update()
 27     {
 28         if (!canMove)
 29         {
 30             return;
 31         }
 32 
 33         //移动过程
 34         timer = timer + Time.deltaTime * timeScale;
 35 
 36         float xOffset = startSpeed * timer * cosValue * horizontalDir.x;
 37         float zOffset = startSpeed * timer * cosValue * horizontalDir.y;
 38         float yOffset = startSpeed * timer * sinValue + 0.5f * gravity * timer * timer;
 39 
 40         Vector3 endPos;
 41         if (!isInRebound) //非反弹过程
 42         {
 43             endPos = startPos + new Vector3(xOffset, yOffset, zOffset);
 44             if (Mathf.Abs(timer - hightestPointTime) < hightestPointStayTime)
 45             {
 46                 timeScale = 0.5f;
 47             }
 48             else
 49             {
 50                 timeScale = 1f;
 51             }
 52         }
 53         else //反弹过程
 54         {
 55             endPos = new Vector3(lastX, yOffset, lastZ);
 56         }
 57 
 58         //落地
 59         if (endPos.y < endY)
 60         {
 61             endPos.y = endY;
 62 
 63             reboundTimes = reboundTimes - 1;
 64             if (reboundTimes < 0) //移动结束
 65             {
 66                 canMove = false;
 67             }
 68             else //落地反弹
 69             {
 70                 gravity = gravityValue * 2;
 71                 horizontalDir = Vector2.zero;
 72                 startSpeed = startSpeed * 0.8f;
 73                 sinValue = 1;
 74                 cosValue = 0;
 75                 timer = 0;
 76 
 77                 isInRebound = true;
 78                 lastX = endPos.x;
 79                 lastZ = endPos.z;
 80             }
 81         }
 82         transform.position = endPos;
 83 
 84         //移动结束
 85         if (!canMove)
 86         {
 87             finishCallBack(gameObject);
 88             Destroy(this);
 89         }
 90     }
 91 
 92     public void StartMove(Vector2 horizontalDir, float startSpeed, float angle, float endY, Action<GameObject> finishCallBack)
 93     {
 94         gravity = gravityValue;
 95         this.horizontalDir = horizontalDir;
 96         this.startSpeed = startSpeed;
 97         sinValue = Mathf.Sin(Mathf.Deg2Rad * angle);
 98         cosValue = Mathf.Cos(Mathf.Deg2Rad * angle);
 99         startPos = transform.position;
100         this.endY = endY;
101         timer = 0;
102         this.finishCallBack = finishCallBack;
103         canMove = true;
104 
105         hightestPointTime = Mathf.Abs(startSpeed * sinValue / gravity);
106     }
107 }

 

TestThrow.cs

 1 using UnityEngine;
 2 using System.Collections.Generic;
 3 
 4 public class TestThrow : 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             ObliqueThrow obliqueThrow = testGo.AddComponent<ObliqueThrow>();
25             obliqueThrow.StartMove(new Vector2(1, 0), 5f, 45f, 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 }

 

效果如下:

posted on 2019-02-21 23:17  艰苦奋斗中  阅读(869)  评论(1编辑  收藏  举报