Unity播放器由于脚本冻结但没有错误

时间:2017-02-21 20:24:12

标签: unity3d

我的团结播放器在一段时间后继续冻结,我知道是什么脚本导致它(如果它确实是一个导致它的脚本)。因为我开始冻结时只编辑了一个脚本。但我无法弄清楚为什么它会冻结! 以下是导致它的脚本:

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

我确实有一个小小的怀疑,即冻结与SpawnPickups方法和/或它在ResetGame方法中销毁拾取器的部分有关。

谢谢!

1 个答案:

答案 0 :(得分:2)

您的方法SpawnPickups正在这样做。 当你调用这个协同程序,并且启用为true并且运行为false时,你永远不会达到&#34; yield&#34;指令,所以你的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
    }
}