我如何检查对象 MoveTowards 何时到达新位置然后旋转它?

How can i check when the object MoveTowards has reached to the new position and then rotate it?

private void MoveToNewFormation()
    {
        squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
        float step = speed * Time.deltaTime;
        for (int i = 0; i < squadMembers.Length; i++)
        {
            squadMembers[i].transform.LookAt(newpos[i]);
            squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
            //squadMembers[i].transform.rotation = qua[i];
        }
    } 

并在更新中调用它:

void Update()
    {
        if (Input.GetKeyDown(KeyCode.F))
        { 
            ChangeFormation();
        }

        if (move == true)
            MoveToNewFormation();
    }

一旦其中一名小队成员到达新位置,我就想

squadMembers[i].transform.rotation = qua[i];

qua 是一个列表,我想在他到达新位置后轮换小队成员。

在 MoveToNewFormation 中,我想在循环之后添加以下行:

if (squadMembers[i].transform.position == newpos[i])
{
  squadMembers[i].transform.rotation = qua[i];
}

但是它在循环之后所以 'i' 不存在。

这是完整的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SquadFormation : MonoBehaviour
{
    enum Formation
    {
        Square, Circle, Triangle
    }

    public Transform squadMemeber;
    public int columns = 4;
    public int squareSpace = 10;
    public int circleSpace = 40;
    public int numberOfObjects = 20;
    public float yOffset = 0;
    public float speed = 3;

    private Formation formation;
    private GameObject[] squadMembers;
    private List<Quaternion> qua = new List<Quaternion>();
    private List<Vector3> newpos = new List<Vector3>();
    private bool move = false;

    // Use this for initialization
    void Start()
    {
        formation = Formation.Square;
        ChangeFormation();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.F))
        {
            ChangeFormation();
        }

        if (move == true)
            MoveToNewFormation();
    }

    private void ChangeFormation()
    {
        switch (formation)
        {
            case Formation.Square:

                FormationSquare();

                break;

            case Formation.Circle:

                FormationCircle();

                break;
        }
    }

    private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
    {
        float posX = (index % columns) * squareSpace;
        float posY = (index / columns) * squareSpace;
        return new Vector3(posX, posY);
    }

    private void FormationSquare()
    {
        for (int i = 0; i < numberOfObjects; i++)
        {
            Transform go = Instantiate(squadMemeber);
            Vector3 pos = FormationSquarePositionCalculation(i);
            go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
            go.Rotate(new Vector3(0, -90, 0));
            go.tag = "Squad Member";
        }
        formation = Formation.Circle;
    }

    private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
    {
        float ang = index * angleIncrement;
        Vector3 pos;
        pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
        pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
        pos.y = center.y;
        return pos;
    }

    private void FormationCircle()
    {        
        Vector3 center = transform.position;
        float radius = (float)circleSpace / 2;
        float angleIncrement = 360 / (float)numberOfObjects;

        for (int i = 0; i < numberOfObjects; i++)
        {
            Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);

            var rot = Quaternion.LookRotation(center - pos);
            pos.y = Terrain.activeTerrain.SampleHeight(pos);
            pos.y = pos.y + yOffset;
            newpos.Add(pos);
            qua.Add(rot);
        }
        move = true;
        formation = Formation.Square;
    }

    private void MoveToNewFormation()
    {
        squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
        float step = speed * Time.deltaTime;
        for (int i = 0; i < squadMembers.Length; i++)
        {
            squadMembers[i].transform.LookAt(newpos[i]);
            squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
            //squadMembers[i].transform.rotation = qua[i];
        }

        //if (squadMembers[i].transform.position == newpos[i])
    }    
}

您可以使用阈值并使用该阈值检查距离。 在脚本开始时像这样定义阈值。

public float threshold = 0.1f;

然后像这样更改 MoveToNewFormation() 函数:

private void MoveToNewFormation()
{
    squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
    float step = speed * Time.deltaTime;
    for (int i = 0; i < squadMembers.Length; i++)
    {
        squadMembers[i].transform.LookAt(newpos[i]);
        squadMembers[i].transform.position = 
        Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
        if(Vector3.Distance(squadMembers[i].transform.position,newpos[i])<threshold){
              squadMembers[i].transform.rotation = qua[i];
        }
    }

    //if (squadMembers[i].transform.position == newpos[i])
}