考虑这样一个需求:敌人出生在A点,需要到达B点去攻击主角。
之前,我是这样实现这个需求的(只考虑Z轴的移动):
1 using UnityEngine;
2
3 public class Test : MonoBehaviour
4 {
5 /// <summary>
6 /// 目标点
7 /// </summary>
8 Vector3 targetPos;
9 /// <summary>
10 /// 移动速度
11 /// </summary>
12 float moveSpeed = 10f;
13
14 // Update is called once per frame
15 void Update()
16 {
17 transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
18 ///这里只考虑在Z轴方向的移动
19 if (Mathf.Abs(transform.position.z - targetPos.z) <= 0.2f)
20 {
21 Debug.Log("到达目标点");
22 }
23 }
24 }
这里有个问题,就是判断是否到达目标点的距离值不好确定,这里设置的是0.2f。这个值应该小于一帧的移动距离(即这里的moveSpeed * Time.deltaTime)。但是呢,这里的 Time.deltaTime不是一个固定的值,在不同的机器上可能值都不同。距离值设置的过小的话,如果小于一帧的移动距离,那么就会一直移动,检测不到到达目标点;如果设置的过大的话,假如速度也很大,那么最后与目标点的差距也会非常大。
改进一下,使用如下的方法实现:
1 using UnityEngine;
2
3 public class Test : MonoBehaviour
4 {
5 /// <summary>
6 /// 目标点
7 /// </summary>
8 Vector3 targetPos;
9 /// <summary>
10 /// 移动速度
11 /// </summary>
12 float moveSpeed = 10f;
13 /// <summary>
14 /// 结束移动的时间
15 /// </summary>
16 float endMoveTm;
17
18 void Start()
19 {
20 float moveTm = Mathf.Abs(transform.position.z - targetPos.z) / moveSpeed;
21 endMoveTm = moveTm + Time.time;
22 }
23
24 // Update is called once per frame
25 void Update()
26 {
27 transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
28 if (Time.time >= endMoveTm)
29 {
30 Debug.Log("到达目标点");
31 }
32 }
33 }
注意:这里的方法只适用于到达固定目标点的匀速运动。
原理:先根据路程和速度,计算出时间。然后根据移动时间,判断是否到达了目标点。
这样的好处,就是可以不用设置到达目标点的标准值了。
网友评论