转向WayPoints [C#]

时间:2017-03-23 19:57:20

标签: c# unity3d move

我遇到了这个问题:我需要敌人朝目标位置移动,但我的问题是我在Update函数中写了这个,所以“foreach”语句只在一帧中完成。此外,从未显示“到达航点”句子。我怎么解决这个问题?

以下是代码:`public class WayPointMovement:MonoBehaviour {

public EnemyDataSpawn enemy;
private Vector3 lastPos; 

void Start ()
{
    lastPos = gameObject.transform.position; 
}

void Update ()
{
    gameObject.transform.LookAt (LevelManager.current.playerObject.transform);
    //WaypointData is a scriptable object that contains the definition of "x" and "z" coordinates.
    foreach (WaypointData waypoints in enemy.enemy.waypoint) {
        Debug.Log (waypoints.x);
        gameObject.transform.position = Vector3.MoveTowards (gameObject.transform.position, new Vector3 (lastPos.x + waypoints.x, 0f, lastPos.z + waypoints.z), Time.deltaTime * enemy.enemy.easySpeedMovement);
        if (gameObject.transform.position.x == lastPos.x + waypoints.x && gameObject.transform.position.z == lastPos.z + waypoints.z) {
            Debug.Log("waypoint reached");
            lastPos = gameObject.transform.position;
        }
    }
}

}`

2 个答案:

答案 0 :(得分:1)

您需要重做Update,这样才能完成一个框架的工作。这意味着你必须记住a)你走向哪个方向点,以及b)你走了多远。当你真正到达它时,你只能移动到下一个航路点。

有两种方法可以通过航点跟踪进度:

<德尔> 1。您可以在到达时简单地删除航点。然后,您尝试前往的航点始终是列表中的第一个。

<德尔> 2。如果你想保留航点,那么你需要一个额外的变量来跟踪你正在当前移动的哪个航路点。这可能类似于数组或列表的索引,也可能是每次完成航点时都调用IEnumerator<WaypointData>的枚举器(MoveNext)。

您已经指出(在此回答的评论中)您不想在到达时删除航点。允许您随意添加新航点的最灵活的安排是使用索引变量:

int waypointIndex;

void Start()
{
  waypointIndex = 0;
}

void Update()
{
  if (waypointIndex < waypoints.Count)
  {
    update position;

    if (reached waypoint)
    {
      waypointIndex++;
    }
  }
}

然后,在你的Update方法中,不是编写循环,而是更新游戏对象的位置一次,检查它是否只到达航点一次,如果有,请继续返回前的下一个航点。如果需要多次移动才能到达航点,您可以允许多次调用Update;每个Update只是运动的一个步骤。

您需要更好的逻辑来确定何时到达航路点。正如其他评论者指出的那样,使用浮点值,只需检查它们是否完全相同就不太可能有效。相反,您可以检查到航点的距离是否小于Time.deltaTime * enemy.enemy.easySpeedMovement,如果是,则不是使用Vector3.MoveTowards,而是将位置精确地设置为航点,并将该步骤视为具有到了航点。

这里是粗略的逻辑(伪代码)(但不像我第一次编写时那样伪代码):

Vector3 lastPos;
int waypointIndex;

void Start()
{
  lastPos = gameObject.transform.position;
  waypointIndex = 0;
}

void Update()
{
  if (waypointIndex < waypoints.Count)
  {
    waypointPosition = new Vector3 (lastPos.x + waypoints.x, 0f, lastPos.z + waypoints.z);

    if (Vector3.Distance(gameObject.transform.position, waypointPosition) > length of one step)
    {
      gameObject.transform.position = Vector3.MoveToward(gameObject.transform.position, waypointPosition);
    }
    else
    {
      gameObject.transform.position = waypointPosition;
      log("Waypoint reached");
      waypointIndex++;
    }
  }
}

答案 1 :(得分:1)

使用Vector3.sqrMagnitude比较亲密度。您可以定义&#34;关闭&#34;足够接近。我将在此示例中将航点用作Vector3。您可以随意确定航路点Vector3

// define this globally
public float closeEnough = 5f;

// Within your compare method
if((gameObject.transform.position - waypoint).sqrMagnitude < closeEnough)
{
   Debug.Log("waypoint reached");
}

注意:Vector3 - Vector3的结果是另一个Vector3