Reputation: 1348
I'm getting an error of "Coroutine couldn't be started because the the game object 'TimeOutWarningDialog' is inactive!" but I'm unsure why I'm getting this error.
Just to give a rundown of the code:
I'm looking for inactivity in GameManger.Update()
If inactive for a period of time I call GameManager.ShowRestartWarning()
TimeOutWarningDialog gets SetActive to true
I check if the object is active before calling StartRestartTimer(), if (timerInstance.activeSelf == true) StartRestartTimer();
I call startTimer() in CountdownTimer class
I'm setting the object that I'm instatiating to 'active' before I call the startTimer function which includes the coroutine. what am I doing wrong here? any help would be great!!
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"));
}
}
then I'm calling startTimer in the CountdownTimer class below:
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));
}
}
}
Upvotes: 2
Views: 7713
Reputation: 17085
The problem is in this method:
void StartRestartTimer()
{
CountdownTimer countdownTimer = timeOutWarningDialog.GetComponent<CountdownTimer>();
countdownTimer.startTimer(countdownLength);
CancelInvoke();
Invoke("RestartGame", countdownLength);
}
You start the coroutine first and then invoke RestartGame
to load another scene. So the object with the coroutine gets destroyed.
I can't give you the solution because it requires more knowledge regarding your scenes but you may want to try additive scene loading.
Upvotes: 1