2017-02-21 17 views
0

После того, как я смогу заново замочить, я знаю, какой сценарий вызывает его (если это действительно сценарий, вызывающий его). так как есть только один сценарий, который я редактировал, когда он начал замораживаться. Но я не могу понять, почему это замерзает! Вот скрипт, который вызывает его:Unity player замерзает из-за скрипта, но без ошибок

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."); 
} 
} 

У меня есть небольшая suspection, что замораживание имеет что-то сделать с помощью метода SpawnPickups и/или той частью, где он разрушает пикапы в методе ResetGame.

Спасибо!

+0

Хм безопасно удалять детей в петле foreach? – AVAVT

+0

Почему бы и нет? –

+0

Ум, я уверен, что это не хорошо, потому что цикл foreach работает по индексу, а не по итератору. Другими словами, это просто другое 'for (int i = 0; i AVAVT

ответ

2

Ваш метод SpawnPickups делает это. Когда вы вызываете эту сопрограмму и включаете true, и работает false, вы никогда не достигаете инструкции «yield», поэтому ваше время (включено) действительно некоторое время (true)

Coroutines - это не потоки, они работают на основной поток, и если вы блокируете сопрограмму, подобную этой, вы блокируете игру.

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 действительно может дать вам некоторые ошибки, но это не приведет к замораживанию вашего приложения, оно просто покажет эти ошибки в консоли и, вероятно, какое-то странное поведение и, возможно, сбой. Но не замерзнет ваше единственное приложение. –