如何循环MoveTowards?

时间:2018-10-24 15:37:55

标签: c# unity3d

在迷你游戏中,我要在Unity中进行的工作是想循环移动。我想将对象移回第一位置,但不仅要移动1次。现在,我有了这段代码,这使我能够“移动到职位和后退系统”。我该如何更改此代码以使移动循环?

public class TestMovement : MonoBehaviour
{
    public float speed = 3;
    public Vector3 target = Vector3.zero;
    private Vector3 origin;

    void Start(){
        origin = transform.position;
    }

    void Update(){
        TestTransform ();
    }


    void TestTransform (){
        transform.position = Vector3.MoveTowards (transform.position, target, speed * Time.deltaTime);
        if (transform.position == target) target = origin;
    }
}

3 个答案:

答案 0 :(得分:2)

TestTransform是从Update调用的,这意味着每帧它都会调用一次。因此,您实际上已经处于一个循环中(只要您的游戏正在运行,便是一个无限循环)。让我们看一下您现有的代码和所需的结果: 您现有的代码将立即开始向目标移动。到达目标后,它将目标切换回原点,并开始向新目标移动。

您的代码是在第一遍将<目标>更改为原始目标。之后,一旦它返回到新的“目标”(现在是“原点”),它就坐在那儿,测试那个transform.position == target,并在每一帧上反复设置target =原点。

如果希望对象在原点和目标之间来回反弹,则需要进行以下更改:

  1. 您需要第三个Vector3(我们将其称为“ currentTarget”)。
  2. 启动时,设置currentTarget = target。
  3. 在TestTransform中,更改要测试的位置,并将“目标”更改为对“ currentTarget”进行操作。更改它时,您需要考虑将currentTarget设置为目标还是原点,然后选择另一个作为下一个目标。

最终结果应为“ currentTarget”在“ target”和“ origin”之间来回更改。

旁注:正如评论中其他人所述,测试向量的精确相等性并不总是可行的-您应该检查向量之间的距离,并等待其小于某个很小的值。

答案 1 :(得分:2)

这使您可以随意移动多个位置,只需为每个目标创建空的GameObject,然后将它们添加到检查器中的列表中即可。当然,如果只希望2个位置在列表中添加2个元素,则变换将循环移动。 (ps。我在脚本中添加了所有内容,只是为了使其易于理解,我建议使用管理目标的逻辑制作另一个方法CheckNextPosition())

   public class TestMovement : MonoBehaviour
    {
        public float speed = 3;
        public List<Transform> targets= new List<Transform();
        public Transform target;
        protected int currentTargetIndex=0;


        void Start(){
            origin = transform.position;
            target= targets[currentTargetIndex];
        }

        void Update(){
            TestTransform ();
        }


        void TestTransform (){
            transform.position = Vector3.MoveTowards (transform.position, target.position, speed * Time.deltaTime);
        if (transform.position == target.position)//check if you reached the target
        {            
            if(currentTargetIndex >= targets.Count)//check if you reached the last position in your targets list
            {
               currentTargetIndex=0;//go to first target in your target list
            }
            else
            {
               currentTargetIndex++;// go to next target in your target list
            }
            target=targets[currentTargetIndex];// set the next target
        }
     }
}

答案 2 :(得分:0)

使用Mathf.PingPong轻松进行振荡。

float distanceBetweenPosts = Vector3.Distance(origin, target);

float distanceTowardTarget = Mathf.PingPong(Time.time * speed, distanceBetweenPosts);

float percentageDistance = distanceTowardTarget / distanceBetweenPosts;

Vector3 currentOffset = (target-origin ) * percentageDistance;

Vector3 currentPosition = origin + currentOffset;

transform.position = currentPosition;

如果您要为从startTime开始的目标设置特定时间origin,则可以使用:

float distanceTowardTarget = Mathf.PingPong((Time.time-startTime) * speed, 
                                            distanceBetweenPosts);