由于不活动的游戏对象,协程无法启动

时间:2017-07-17 03:05:46

标签: c# unity3d coroutine

我收到错误消息,我不确定如何解决。我试图在短暂的闲置之后开始倒计时,然后开始第二次倒计时与视觉警告配对。一旦协程开始我就会收到这个错误:

无法启动协程,因为游戏对象'_CountdownTimer'处于非活动状态! UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator的) CountdownTimer:StartPreCountTimer()(在Assets / _Components / _Scripts / CountdownTimer.cs:38) GameManager:CheckUserActivity()(在Assets / _Components / _Scripts / GameManager.cs:68)

我错过了什么?我需要在哪里设置_CountdownTimer的活动状态?谢谢!!

GameManager.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour 
{
    public static GameManager gameManagerInstance = null; // Create Singleton

    public float checkUserActivityInterval;
    public GameObject loader;
    public GameObject countdownTimer;
    private GameObject gameManager; 

    private Vector3 currentMousePosition;
    private Vector3 prevMousePosition;
    private CountdownTimer countdownInstance;
    private Scene currentScene;
    public Color defaultBackgroundColor;                 
    public Object startingScene;

    public static bool userActive;
    public static bool preCountActive;
    public static bool restartWarningActive;

    public static string animalDataFilePathJSON;
    public static string animalDataFilePathTex;

    void Awake ()
    {
        if (CountdownTimer.countdownTimerInstance == null)
            Instantiate(countdownTimer);

        if (gameManagerInstance == null)
            gameManagerInstance = this;
        else if (gameManagerInstance != null)
            Destroy(gameObject);

        DontDestroyOnLoad(gameObject);
    }

    void Start()
    {
        prevMousePosition = Input.mousePosition;
        countdownInstance = countdownTimer.GetComponent<CountdownTimer>(); // Create an instance of CountdownTimer
        InvokeRepeating("CheckUserActivity", 0, checkUserActivityInterval);
        InvokeRepeating("SetPrevMousePosition", 0, checkUserActivityInterval);
    }

    void Update()
    {
        currentScene = SceneManager.GetActiveScene();
        currentMousePosition = Input.mousePosition;
    }

    void CheckUserActivity()
    {
        if (currentScene.name != startingScene.name)
        {
            if (currentMousePosition == prevMousePosition)
            {
                Debug.Log("MOUSE HAS NOT MOVED!!");
                userActive = false;

                if (!userActive && !preCountActive)
                    countdownInstance.StartPreCountTimer();
            }

            if (currentMousePosition != prevMousePosition)
            {
                Debug.Log("MOUSE HAS MOVED!!");
                userActive = true;

                if (preCountActive == true)
                    countdownInstance.RestartPreCountTimer();
            }
        }
    }

    void SetPrevMousePosition()
    {
        prevMousePosition = Input.mousePosition;
    }
}

CountdownTimer.cs

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class CountdownTimer : MonoBehaviour
{
    public static CountdownTimer countdownTimerInstance = null; // Create Singleton

    public Object startingScene;
    public GameObject timeOutWarningDialog;
    private GameObject timerDialogBoxInstance;
    private GameObject canvas; 

    private IEnumerator counter;
    private Button stopCountButton;
    private Text timerTextField;

    public float countdownLength;
    public float countdownDelay;
    private float countdownInterval = 1;

    void Awake()
    {
        if (countdownTimerInstance == null)
            countdownTimerInstance = this;
        else if (countdownTimerInstance != null)
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);
    }

    public void StartPreCountTimer()
    {
        GameManager.preCountActive = true;
        GameManager.restartWarningActive = false;

        counter = RunTimer(countdownDelay); // create new reference to counter
        StartCoroutine(counter);
    }

    public void RestartPreCountTimer()
    {
        GameManager.preCountActive = false;
        StopTimer();
    }

    void ShowRestartWarning()
    {
        GameManager.preCountActive = false;
        GameManager.restartWarningActive = true;

        canvas = GameObject.FindGameObjectWithTag("Canvas");

        timerDialogBoxInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
        timerDialogBoxInstance.transform.SetParent(canvas.transform, false);
        timerDialogBoxInstance.SetActive(true);

        Text[] textFields = timerDialogBoxInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
        timerTextField = textFields[2]; // access and assign countdown textfield

        stopCountButton = timerDialogBoxInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
        stopCountButton.onClick.AddListener(StopTimer); // add button listener

        if (timerDialogBoxInstance.activeInHierarchy == true)
        {
            counter = RunTimer(countdownLength); // create new reference to counter, resets countdown to countdownLength
            StartCoroutine(counter);
        }
    }

    IEnumerator RunTimer(float seconds)
    {
        float s = seconds;
        while (s > -1)
        {
            if (GameManager.restartWarningActive == true)
                if (timerTextField != null)
                    timerTextField.text = s.ToString();

            yield return new WaitForSeconds(countdownInterval);
            s -= countdownInterval;
        }

        if (s == -1)
        {
            if (GameManager.restartWarningActive == true)
                RestartGame();
        }
    }

    void StopTimer()
    {
        Debug.Log("Restart Cancelled");
        StopCoroutine(counter);
        Destroy(timerDialogBoxInstance);
    }

    void RestartGame()
    {
        SceneManager.LoadScene(startingScene.name);
    }
}

1 个答案:

答案 0 :(得分:1)

我想我知道你的错误在哪里。当您创建countdownTimer的实例时。您必须存储对它的引用才能获得基础 CountdownTimer 类。

尝试在 GameManager

中执行此操作
private GameObject countDownTimerInstance;

<强>醒()

countDownTimerInstance = Instantiate(countdownTimer);

并在开始()执行,

countdownInstance = countdownTimerInstance.GetComponent<CountdownTimer>();

我认为问题在于您是直接访问预制件的getComponent()而不是 实例化的游戏对象 CountdownTimer!。