2017-02-21 2 views
0

私のユニティプレーヤーはしばらくしてもフリーズし続けていますが、実際にそれを引き起こしているスクリプトが何かを知っています。私が凍結を開始したときに私が編集したスクリプトは1つしかないからです。でも、なぜ凍っているのか分かりません!私は凍結がSpawnPickups方法および/またはそれがResetGame方法でピックアップを破壊する部分とは何かを持っていることを小さなsuspectionを持っていますスクリプトによるユニティプレーヤーのフリーズ

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 
using UnityEngine.UI; 
public class GameManager : MonoBehaviour { 

//public GameObject allPlayersPrefab; 
public GameObject allPlayers; 
public Transform playerRed; 
public Transform playerGreen; 
//public Transform playerPurple; 
//public Transform playerYellow; 

//Tail redTail; 
//Tail greenTail; 
//Tail purpleTail; 
//Tail yellowTail; 

public float secondsBetweenGaps = 2f; 
public float secondsToGap = .25f; 

public float snakeSpeed = 3f; 
public float turnSpeed = 200f; 

public int biggerPickupDuration = 3; 
public int smallerPickupDuration = 3; 
public int speedPickupDuration = 2; 
public int invinciblePickupDuration = 3; 

public int maxPickups = 3; 
public int spawnPickupThreshold = 5; 
private GameObject[] currPickups; 
public GameObject[] pickupTypes; 
public Transform pickupsParent; 

public int players = 2; 

[HideInInspector] 
public int alive; 

public bool enableKeys = false; 

public GameObject prefabTail; 
public GameObject settingsMenu; 
public GameObject startingPanel; 

public Text scoreText; 
public Text radiusText; 
public Text speedText; 

public Text winText; 

private bool hasEnded = false; 
[HideInInspector] 
public bool playerWon = false; 
public bool running; 

public Snake[] snakes; 

ButtonManager buttonManager; 
Pickup[] pickups; 

void Start() { 
    //InstantiateNewPlayers(); 
    playerRed = allPlayers.transform.FindChild("Red"); 
    playerGreen = allPlayers.transform.FindChild("Green"); 
    snakes = allPlayers.GetComponentsInChildren<Snake>(true); 
    alive = players; 
    //redTail = playerRed.GetComponentInChildren<Tail>(); 
    //greenTail = playerGreen.GetComponentInChildren<Tail>(); 
    //purpleTail = playerPurple.GetComponentInChildren<Tail>(); 
    //yellowTail = playerYellow.GetComponentInChildren<Tail>(); 

    buttonManager = FindObjectOfType<ButtonManager>(); 

    pickups = FindObjectsOfType<Pickup>(); 

    playerRed.gameObject.SetActive(false); 
    playerGreen.gameObject.SetActive(false); 
    //playerPurple.gameObject.SetActive(false); 
    //playerYellow.gameObject.SetActive(false); 

    winText.enabled = false; 

    foreach(Snake snake in snakes) { 
     snake.scoreText.enabled = false; 
    } 
} 

void Update() { 
    if(Input.GetKey(KeyCode.Escape)) { 
     foreach(Snake snake in snakes) { 
      snake.score = 0; 
      snake.scoreText.text = "0"; 
     } 

     buttonManager.anima.Play("BackToSettings"); 
     playerWon = true; 
     ResetGame(); 
     buttonManager.restartButt.gameObject.SetActive(false); 
     buttonManager.StopAllCoroutines(); 
     buttonManager.countDownText.enabled = false; 
     winText.enabled = false; 

     foreach(Snake snake in snakes) { 
      snake.scoreText.enabled = false; 
     } 
    } 

    if(alive == 1 && !hasEnded) { 
     Transform lastPlayer; 
     foreach(Snake child in snakes) { 
      if(!child.dead) { 
       lastPlayer = child.transform.parent; 
       if(child.score >= int.Parse(scoreText.text)) { 
        Win(lastPlayer.name); 
        AllPlayersDead(); 
       } else 
        AllPlayersDead(); 
       break; 
      } 
     } 
    } 

    if(alive == 0) { 
     if(hasEnded) 
      return; 

     buttonManager.restartButt.gameObject.SetActive(true); 
     hasEnded = true; 
     running = false; 
    } 

    foreach(Snake child in snakes) { 
     if(child.score >= int.Parse(scoreText.text)) { 
      AllPlayersDead(); 
      Win(child.transform.parent.name); 
     } 
    } 
} 

public void AllPlayersDead() { 
    if(hasEnded) 
     return; 

    buttonManager.restartButt.gameObject.SetActive(true); 
    hasEnded = true; 
    running = false; 
} 

void Win(string winningPlayer) { 

    foreach(Snake snake in snakes) { 
     snake.score = 0; 
     snake.scoreText.text = "0"; 
    } 
    Debug.Log("Win got called"); 
    winText.gameObject.SetActive(true); 
    winText.enabled = true; 
    winText.text = winningPlayer + " wins!"; 
    playerWon = true; 
    running = false; 
} 

public void PlayerDied() { 
    foreach(Snake child in snakes) { 
     if(!child.dead) { 
      child.score += 1; 
     } 
    } 
} 

public IEnumerator SpawnPickups() { 
    while(enabled) { 
     Debug.Log("SpawnPickups running..."); 
     if(running) { 
      if(pickupsParent.childCount < maxPickups) { 
       int type = Random.Range(0, pickupTypes.Length); 
       float X = Random.Range(-7f, 7f); 
       float Y = Random.Range(-3f, 3f); 
       Vector3 spawnPos = new Vector3(X, Y, 0); 
       /*GameObject newPickup = */Instantiate(pickupTypes[type], spawnPos, Quaternion.Euler(0, 0, 0), pickupsParent); 
       Debug.Log("SpawnPickups instantiated new pickup..."); 
       yield return new WaitForSeconds(spawnPickupThreshold); 
      } 
     } 
    } 
} 

public void ResetGame() { 
    Debug.Log("Resetting everything..."); 
    for(int i = 0; i < players; i++) { 

     Transform currPlayer = allPlayers.transform.GetChild(i); 
     currPlayer.GetComponentInChildren<Tail>().points.Clear(); 
     currPlayer.GetComponentInChildren<Snake>().dead = false; 
     currPlayer.GetComponentInChildren<Snake>().invincible = false; 
     currPlayer.GetComponentInChildren<Snake>().posInformer.position = new Vector3(-20, 0, 0); 
     if(playerWon) { 
      currPlayer.GetComponentInChildren<Snake>().score = 0; 
      playerWon = false; 
     } 

     //currPlayer.GetComponentInChildren<LineRenderer>().positionCount = 0; 
     currPlayer.GetComponentInChildren<LineRenderer>().numPositions = 0; 

     List<Vector2> list = new List<Vector2>(); 
     list.Add(new Vector2(0, 5)); 
     list.Add(new Vector2(0, 6)); 

     StopAllCoroutines(); 

     for(int i2 = 0; i2 < pickups.Length; i2++) { 
      pickups[i2].StopAllCoroutines(); 
     } 

     foreach(Transform pickup in pickupsParent) { 
      Destroy(pickup.gameObject); 
     } 

     currPlayer.GetComponentInChildren<EdgeCollider2D>().points = list.ToArray(); 

     foreach(Transform child in currPlayer) { 
      if(child.CompareTag("PrefabTail")) { 
       Destroy(child.gameObject); 
      } 
     } 

     currPlayer.gameObject.SetActive(false); 
     currPlayer.GetComponentInChildren<Tail>().enabled = true; 
     Destroy(GameObject.FindWithTag("PrefabTail")); 

     turnSpeed = int.Parse(radiusText.text) * 10; 
     snakeSpeed = float.Parse(speedText.text); 
     alive = players; 
     hasEnded = false; 
     running = false; 
    } 

    Debug.Log("Resetting done."); 
} 
} 

: はここでそれを引き起こしているスクリプトです。

ありがとうございます!

+0

これは、foreachループで子供を削除するのは安全ですか? – AVAVT

+0

それはなぜでしょうか? –

+0

私はforeachループがイテレータではなくインデックスによって実行されるので、それは良くないと確信しています。言い換えれば、ループ中にn番目の要素を削除すると、(n + 1)番目の要素はn番目の要素になります(for int i = 0; i AVAVT

答えて

2

あなたのメソッドSpawnPickupsがこれをしています。 このコルーチンを呼び出すとenableがtrueで実行がfalseの場合、 "yield"命令に達することはありません。したがって、while(有効)は実際には真です(真)

コルーチンはスレッドではなく、メインスレッドと、このようなコルーチンをブロックすると、あなたはゲームをブロックしています。

public IEnumerator SpawnPickups() { 
    while(enabled) { 
     Debug.Log("SpawnPickups running..."); 
     if(running) { 
      if(pickupsParent.childCount < maxPickups) { 
       int type = Random.Range(0, pickupTypes.Length); 
       float X = Random.Range(-7f, 7f); 
       float Y = Random.Range(-3f, 3f); 
       Vector3 spawnPos = new Vector3(X, Y, 0); 
       /*GameObject newPickup = */Instantiate(pickupTypes[type], spawnPos, Quaternion.Euler(0, 0, 0), pickupsParent); 
       Debug.Log("SpawnPickups instantiated new pickup..."); 
       yield return new WaitForSeconds(spawnPickupThreshold); 
      } 
      //Here you need some yield in case running is true but you reached maxPickups (this one is not necessary if you put the next one) 
     } 
     //Here you need some yield in case running is false 
     //yield return null; //this should be enough to prevent your game from freezing 
    } 
} 
+0

もう凍結していません!しかし、それは私に間違いを与えていない奇妙ではないですか?ああ、あなたはforeachループ(AVAVTは何について話していたのですか?)でオブジェクトを破壊することについてどう思いますか? –

+0

"失敗"していないので、エラーが発生していないというのは完全に正常です。無限ループに止まってしまっているだけです。 –

+0

foreachループ内のオブジェクトを破棄すると、実際にはエラーが発生する可能性がありますが、アプリケーションをフリーズすることはなく、コンソールにエラーが表示され、おそらく奇妙な動作になり、クラッシュする可能性があります。 しかし、ユニティアプリはフリーズしません。 –

関連する問題