2017-12-11 12 views
0

これは私がStartCoroutineを使用しようとしている部分です:StartCoroutineを使用しているときにユニティエディタプログラムがエラーメッセージでシャットダウンするのはなぜですか?

//StartCoroutine(movement()); 
    } 

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

     yield return new WaitForSeconds(0.5f); 
    } 

今私はそれを使用していないが、私はそれを使用行うとき、私はこのエラーを取得していますし、プログラムが近くにあります:

Close

次に、私はプログラムを選択するか、デバッグするか閉じなければなりません。 私がしたいのは、プレイヤーを0.5秒ごとに位置を変えるようにすることです。あなたはFindDirections()呼び出しコルーチンmovement()インサイド

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; 
    } 
} 

答えて

4

FindDirections()の内部では、movement()を開始します。あなたがFindDirections()を呼び出して...というように。..

コルーチンmovement()の内部でも、あなたはUpdate()メソッド内FindDirections()を呼び出しています。方法更新is called every frame(あなたのゲームは30FPSで動作している場合ので、このUpdateが毎秒30回実行されます)ので、あなたは、メソッドを呼び出します別の方法Bを呼び出す方法すべてのフレームを呼び出しているAなどです。Update()の中で何が呼び出されているか慎重にすることをお勧めします。

おそらく、あなたはStackOverFlowException(はい、このウェブサイトと同じ名前)を取得しています。何らかの理由でUnityがクラッシュした場合、何が起きたかを理解する方法はlogsです。

+0

ご了承ください。それでは、どうすれば更新だけを使って呼び出すことができますか?たとえば、FindDirectionsを呼び出して、彼が直面している方向に応じてプレイヤーを1.5距離だけ動かすために、毎秒または1秒に1秒を望みます。 FindDirectionsを呼び出すと、毎回新しい方向が与えられ、プレイヤーはその方向に向かいます。 –

+0

まあ、いつ呼び出すのかを定義する必要があります。FindDirections()とb.- Movement()。今では両者がもう一方を呼び、それが一つの問題です。したがって、例えば、あなたは 'Update()'でのみ呼び出すことができます。 'FindDirections()'と 'Movement()'を呼び出し、 'Movement'内の' FindDirections'への参照と 'FindDirections'内の' Movement'への参照を削除します。 あなたのコードの一部( 'movement')は特定の方向に従おうとし、コードの別の部分(' FindDirections')はいくつかの規則を満たす方向を設定しようとします。 – mayo

+0

私はまた、最初にどのくらい頻繁にあなたがしたいと思うことをお勧めします。 - プレーヤーをある方向に動かし、b。 - 目標方向を更新します。 x秒後にいくつかの要素を呼び出すには、これを確認することができます:https://answers.unity.com/questions/1220440/how-to-display-call-a-function-every-second.html – mayo

3

Mayoのanswerで問題がうまく説明されました。これは、あなたがしたいことを達成する方法を示しています。

私は、プレイヤーに0.5秒ごとに位置を変更させたいと思っています。

代わりの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秒を実行します。

関連する問題