为什么在使用 StartCoroutine 时 unity 编辑器程序关闭并显示错误消息?

Why when using StartCoroutine the unity editor program shut down with error message?

这是我尝试使用 StartCoroutine 的部分:

//StartCoroutine(movement());
    }

    IEnumerator movement()
    {
        player.localPosition += selectedDirection;
        FindDirections();

        yield return new WaitForSeconds(0.5f);
    }

现在我没有使用它,但是当我使用它时,我收到了这个错误并且程序已关闭:

然后我必须 select 或调试或关闭程序 我想要的是让玩家每 0.5 秒改变一次位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.IO;

public class PathFinder : MonoBehaviour
{
    public Transform player;
    public float playerMoveSpeed = 1f;
    public float playerRotationSpeed = 0.5f;
    public float distanceToTravel = 1f;
    public bool randomPath = true;
    public List<Vector3> possibleDirections = new List<Vector3>();
    public Vector3 selectedDirection;

    private Transform start;
    private Transform end;
    private GridGenerator gridgenerator;
    private float m_distanceTraveled = 0f;
    private List<Vector3> visitedList = new List<Vector3>();
    private List<Vector3> toBeVisitedList = new List<Vector3>();
    private Vector3 playerPosition;
    private const float margin = 0.001f;

    public void FindPath()
    {
        gridgenerator = GetComponent<GridGenerator>();
        GenerateStartEnd();
        FindDirections();
        m_distanceTraveled = 0;
    }

    private void FindDirections()
    {
        possibleDirections = new List<Vector3>();
        playerPosition = player.localPosition;
        m_distanceTraveled = 0;

        if (playerPosition.x > 1)
        {
            // can go left
            possibleDirections.Add(Vector3.left);
        }

        if (playerPosition.x + gridgenerator.spaceBetweenBlocks < gridgenerator.gridWidth * gridgenerator.spaceBetweenBlocks)
        {
            // can go right
            possibleDirections.Add(Vector3.right);
        }

        if (playerPosition.z > 1)
        {
            // can go backward
            possibleDirections.Add(Vector3.back);
        }


        if (playerPosition.z + gridgenerator.spaceBetweenBlocks < gridgenerator.gridHeight * gridgenerator.spaceBetweenBlocks)
        {
            // can go forward
            possibleDirections.Add(Vector3.forward);
        }

        if (randomPath == true)
        {
            selectedDirection = possibleDirections[Random.Range(0, possibleDirections.Count)];
        }

        player.forward = selectedDirection;

        //StartCoroutine(movement());
    }

    IEnumerator movement()
    {
        player.localPosition += selectedDirection;
        FindDirections();

        yield return new WaitForSeconds(0.5f);
    }

    private void Update()
    {

        /*if (m_distanceTraveled < distanceToTravel)
        {
            Vector3 oldPosition = player.localPosition;
            player.localPosition += selectedDirection * Time.deltaTime * playerMoveSpeed;
            m_distanceTraveled += Vector3.Distance(oldPosition, player.localPosition);
        }

        if (m_distanceTraveled > distanceToTravel)
        {
            FindDirections();
        }*/
    }

    private List<Vector3> GenerateStartEnd()
    {
        GameObject walls = GameObject.Find("Walls");
        List<Transform> wallsParents = new List<Transform>();
        List<Vector3> startEndPos = new List<Vector3>();

        foreach (Transform child in walls.transform)
        {
            wallsParents.Add(child);
        }

        for (int i = 0; i < 2; i++)
        {
            wallsParents.Remove(wallsParents[Random.Range(0, wallsParents.Count)]);
        }

        var childsWall0 = wallsParents[0].GetComponentsInChildren<Transform>().ToList();
        var childsWall1 = wallsParents[1].GetComponentsInChildren<Transform>().ToList();
        childsWall0.RemoveAt(0);
        childsWall1.RemoveAt(0);

        start = childsWall0[Random.Range(0, childsWall0.Count)];
        player.position = start.position;
        end = childsWall1[Random.Range(0, childsWall1.Count)];
        end.tag = "End";
        startEndPos.Add(start.position);
        startEndPos.Add(end.position);

        start.GetComponent<Renderer>().material.color = Color.red;
        end.GetComponent<Renderer>().material.color = Color.blue;

        return startEndPos;
    }
}

在协程 movement() 中调用 FindDirections()。在 FindDirections() 内,您现在开始 movement();在协程 movement() 中你调用 FindDirections()... 等等......

此外,您正在 Update() 方法中调用 FindDirections()。方法 Update is called every frame(所以如果你的游戏是 运行 30FPS 这个 Update 将每秒执行 30 次),所以,你在每一帧调用一个方法 A 将调用另一个方法 B,将调用方法 A,等等。我建议您注意什么你是在 Update().

里面调用吗

所以,您可能得到 WhosebugException (yes, the same name that this website has). If for any reason Unity crash, a way to understand what happened is check the logs

Mayo 的 很好地解释了您的问题。这向您展示了如何完成您想要做的事情。

I want is to make the player to change position each 0.5 seconds.

不要每次都在 FindDirections 函数中调用 movement 函数,而是调用它 一次 然后在 while 中执行你的代码环形。这应该可以解决您的问题。只需将 StartCoroutine(movement());FindDirections 函数移动到 Start 函数或调用它一次的地方。以下是您的新 movement 代码。

IEnumerator movement()
{
    while (true)
    {
        player.localPosition += selectedDirection;


        FindDirections();

        yield return new WaitForSeconds(0.5f);
    }
}

上面的 while 循环将每 0.5f 秒执行一次。