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

时间:2017-12-11 05:58:25

标签: c# unity3d unity5

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

//StartCoroutine(movement());
    }

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

        yield return new WaitForSeconds(0.5f);
    }

现在我没有使用它,但是当我使用它时,我收到此错误并且程序已接近:

Close

然后我必须选择或调试或关闭程序 我想要的是让玩家每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;
    }
}

2 个答案:

答案 0 :(得分:4)

在协程movement()内,您拨打FindDirections()。在FindDirections()内,您现在开始movement();在协程movement()内,您可以调用FindDirections() ...等等..

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

所以,可能你得到的是StackOverFlowException(是的,与本网站的名称相同)。如果因为任何原因Unity崩溃,了解发生了什么的方法是检查logs

答案 1 :(得分:3)

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

  

我想让玩家每0.5秒换一次位置。

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

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


        FindDirections();

        yield return new WaitForSeconds(0.5f);
    }
}

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