协程因游戏对象无效而无法启动 [英] Coroutine not starting due to inactive game object

查看:231
本文介绍了协程因游戏对象无效而无法启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到一条错误消息,但我不确定如何解决.我正在尝试在闲置一小段时间后开始倒计时,然后再启动第二次倒计时并与视觉警告配对.当协程启动时,我会收到此错误:

I'm getting an error message and I'm not exactly sure how to solve. I'm trying to start a countdown after a short period of idleness that then kicks off a second countdown that is paired with a visual warning. As soon as the coroutine kicks on I'm getting this error:

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

Coroutine couldn't be started because the the game object '_CountdownTimer' is inactive! UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) CountdownTimer:StartPreCountTimer() (at Assets/_Components/_Scripts/CountdownTimer.cs:38) GameManager:CheckUserActivity() (at Assets/_Components/_Scripts/GameManager.cs:68)

我想念什么?我在哪里需要设置_CountdownTimer的活动状态?谢谢!!

What am I missing? Where would I need to set the active state of _CountdownTimer? Thank you!!

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

推荐答案

我想我知道您的错误在哪里.创建countdownTimer的实例时.您必须存储对它的引用,以获取基础的 CountdownTimer 类.

I think I know where your error is. When you create an instance of the countdownTimer. You have to store a reference to it in order to get the underlying CountdownTimer class.

尝试在您的 GameManager

private GameObject countDownTimerInstance;

唤醒()

countDownTimerInstance = Instantiate(countdownTimer);

,然后在 Start()

countdownInstance = countdownTimerInstance.GetComponent<CountdownTimer>();

我认为问题在于您是直接访问 prefab的getComponent(),而不是 实例化的gameObject的 CountdownTimer!.

I think the problem was you were directly accessing the prefab's getComponent() instead of the instantiated gameObject's CountdownTimer!.

这篇关于协程因游戏对象无效而无法启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆