无法启动协程,因为游戏对象处于非活动状态

Posted

技术标签:

【中文标题】无法启动协程,因为游戏对象处于非活动状态【英文标题】:Coroutine couldn't be started because the the game object is inactive 【发布时间】:2017-11-14 01:35:23 【问题描述】:

我收到错误消息“无法启动协程,因为游戏对象 'TimeOutWarningDialog' 处于非活动状态!”但我不确定为什么会收到此错误。

只是给出代码的概要:

    我正在寻找 GameManger.Update() 中的非活动状态

    如果一段时间不活动,我会调用 GameManager.ShowRestartWarning()

    TimeOutWarningDialog 将 SetActive 设置为 true

    我在调用 StartRestartTimer() 之前检查对象是否处于活动状态,如果 (timerInstance.activeSelf == true) StartRestartTimer();

    我在 CountdownTimer 类中调用 startTimer()

在调用包含协程的 startTimer 函数之前,我正在将要实例化的对象设置为“活动”。我在这里做错了什么? 任何帮助都会很棒!

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour 

    // Create Singleton
    public static GameManager instance = null;

    // Set Default Background Color
    public Color defaultColor;

    // Restart variables
    private Vector3 prevMousePosition;
    public GameObject timeOutWarningDialog;
    public GameObject restartDialog;
    public float countdownLength;
    public float timeUntilCountdown;

    // Game Controller
    private GameObject canvas;
    private GameObject gameManager;
    public GameObject timerInstance;
    public Object startingScene;
    private Scene currentScene;

    // File System List of Folders
    public List<string> folders;

    void Awake()
    
        if (instance == null)
            instance = this;
        else if (instance != null)
            Destroy(gameObject);

        DontDestroyOnLoad(gameObject);

        gameManager = GameObject.FindGameObjectWithTag("GameManager");
    

    void Start()
           
        prevMousePosition = Input.mousePosition;
        currentScene = SceneManager.GetActiveScene();
    

    void Update()
    
        if(Input.anyKeyDown || Input.mousePosition != prevMousePosition)
            if(currentScene.name != startingScene.name)
                StartGameTimer();
        prevMousePosition = Input.mousePosition;
    

    // GAME TIMER

    void StartGameTimer()
    
        //  Debug.Log("Game Timer Started");
        CancelInvoke();

        if (GameObject.FindGameObjectWithTag("Timer") == null)
            Invoke("ShowRestartWarning", timeUntilCountdown);
    

    void ShowRestartWarning()
    
        canvas = GameObject.FindGameObjectWithTag("Canvas");

        timerInstance = Instantiate(timeOutWarningDialog);
        timerInstance.transform.SetParent(canvas.transform, false);
        timerInstance.SetActive(true);

        if (timerInstance.activeSelf == true)
            StartRestartTimer();
    

    void StartRestartTimer()
    
        CountdownTimer countdownTimer = timeOutWarningDialog.GetComponent<CountdownTimer>();
        countdownTimer.startTimer(countdownLength);

        CancelInvoke();
        Invoke("RestartGame", countdownLength);
    

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

        Debug.Log("Game Restarted");
        Debug.Log("Current Scene is " + currentScene.name + ".");
    

    void DestroyTimer()
    
        Destroy(GameObject.FindGameObjectWithTag("Timer"));
    

然后我在下面的 CountdownTimer 类中调用 startTimer:

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

public class CountdownTimer : MonoBehaviour

    public float countdownLength;
    public Text timerText;
    public bool stop = true;
    private float minutes;
    private float seconds;

    public void startTimer(float from)
    
        stop = false;
        countdownLength = from;
        Update();
        StartCoroutine(updateCoroutine());
    

    void Update()
    
        if (stop) return;
        countdownLength -= Time.deltaTime;

        minutes = Mathf.Floor(countdownLength / 60);
        seconds = countdownLength % 60;
        if (seconds > 59) seconds = 59;
        if (minutes < 0)
        
            stop = true;
            minutes = 0;
            seconds = 0;
        
    

    private IEnumerator updateCoroutine()
    
        while (!stop)
        
            timerText.text = string.Format("0:0:1:00", minutes, seconds);
            yield return new WaitForSeconds(0.2f);
            Debug.Log(string.Format("0:0:1:00", minutes, seconds));
        
    

【问题讨论】:

也许它的祖先之一,比如canvas.transform,是不活跃的? 【参考方案1】:

问题出在这个方法上:

void StartRestartTimer()

    CountdownTimer countdownTimer = timeOutWarningDialog.GetComponent<CountdownTimer>();
    countdownTimer.startTimer(countdownLength);

    CancelInvoke();
    Invoke("RestartGame", countdownLength);

您首先启动协程,然后调用RestartGame 加载另一个场景。所以带有协程的对象被销毁了。


我无法为您提供解决方案,因为它需要有关您的场景的更多知识,但您可能想尝试添加场景加载。

【讨论】:

以上是关于无法启动协程,因为游戏对象处于非活动状态的主要内容,如果未能解决你的问题,请参考以下文章

应用内购买沙盒之谜:手机处于无法启动购买状态

使用搜索栏时无法使表格视图处于非活动状态。苹果手机

Discord Bot 错误:无法向刚启动的协程发送非无值

Unity,协程无法启动

TypeError:无法向刚启动的协程发送非无值

电脑无法启动是啥原因