团结角色快速移动

时间:2018-02-07 04:56:42

标签: c# unity3d unity5

我试图为敌人编写一个AI,以便他每秒都移动到一个新的可用方块。我把他放在瓷砖地图上的一个点上,附有一个脚本。由于我不希望他每一帧都试图选择一个新的方向,我做了一些研究,看起来最好的选择就是做一个协同程序,这样它就不会发生任何事情。 t执行每一帧。我已经尝试了几个小时在更新功能中写这种不同的方式,在IEnumerator中,打开了各种各样的检查,但到目前为止,我的角色似乎总是像乒乓球一样弹跳或静止不动。这是我现在在协程中的代码。

IEnumerator iMove()
{
    List<string> available = new List<string>();

    available.Add("North");
    available.Add("South");
    available.Add("East");
    available.Add("West");

    if (tilemap.GetTile(new Vector3Int(currentX, currentY + 1, 0)) == null || tilemap.GetTile(new Vector3Int(currentX, currentY + 1, 0)).name != floor || myStack.Contains(new int[] { currentX, currentY + 1 }))
    {
        available.Remove("North");
    }
    if (tilemap.GetTile(new Vector3Int(currentX, currentY - 1, 0)) == null || tilemap.GetTile(new Vector3Int(currentX, currentY - 1, 0)).name != floor || myStack.Contains(new int[] { currentX, currentY - 1 }))
    {
        available.Remove("South");
    }
    if (tilemap.GetTile(new Vector3Int(currentX - 1, currentY, 0)) == null || tilemap.GetTile(new Vector3Int(currentX - 1, currentY, 0)).name != floor || myStack.Contains(new int[] { currentX - 1, currentY }))
    {
        available.Remove("West");
    }
    if (tilemap.GetTile(new Vector3Int(currentX + 1, currentY, 0)) == null || tilemap.GetTile(new Vector3Int(currentX + 1, currentY, 0)).name != floor || myStack.Contains(new int[] { currentX + 1, currentY }))
    {
        available.Remove("East");
    }

    if (available.Count > 0)
    {
        int random = Random.Range(0, (available.Count));
        string direction = available[random];
        Debug.Log("attempting to move..." + direction);
        switch (direction)
        {
            case "North":
                moveVector.y = 1f;
                moveVector.x = 0;
                currentY += 1;
                break;
            case "South":
                moveVector.y = -1f;
                moveVector.x = 0;
                currentY -= 1;
                break;
            case "East":
                moveVector.y = 0;
                moveVector.x = -1f;
                currentX += 1;
                break;
            case "West":
                moveVector.y = 0;
                moveVector.x = 1f;
                currentX -= 1;
                break;
        }
        Debug.Log("current goal:" + currentX + "," + currentY);
        myStack.Push(new int[] { currentX, currentY });
    }
    else
    {
        int[] test = myStack.Pop();

        currentX = test[0];
        currentY = test[1];
    }

    yield return new WaitForSeconds(1);
    transform.position = new Vector3Int(currentX, currentY, 0);
    moveState = MoveState.Walk;
    anim.SetFloat("moveX", moveVector.x);
    anim.SetFloat("moveY", moveVector.y);
    anim.SetBool("isMoving", true);
    yield return new WaitForSeconds(1);
}

1 个答案:

答案 0 :(得分:1)

这取决于你如何启动协程。如果你开始在Update,当然它将在每一帧开始,你将同时运行许多协同程序。

尝试只启动一次:

public void Start()
{
    StartCoroutine(iMove());
}

现在,它会执行一次,所以你会看到你的玩家移动一次。如果你想重复一遍,你可以:

1)在协程中添加while循环

IEnumerator iMove()
{
    while(true) // or a boolean condition that you can set yourself
    {
        // Your code
        // ...
        yield return new WaitForSeconds(1f);
    }
}

这样它会等待一秒钟,回到循环的开始并再次执行

另一种可能性是在完成后再次启动协同程序:

IEnumerator iMove()
{
    // Your code
    // ...
    yield return new WaitForSeconds(1f);

    StartCoroutine(iMove());
}

最后,请注意,当您销毁游戏对象时,此协程将被销毁。您也可以致电StopAllCoroutines()

停止播放