For some reason when my countdown timer hits zero it will not reset when I play the scene again and I cannot figure out why. I put some code in there to have it continue across scenes, but I do not think that should be where the issue might be. Any help is greatly appreciated.
Here is the script for it.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
public class Timer : MonoBehaviour
{
public TextMeshProUGUI timerText;
public float remainingTime;
public bool timerOn;
public bool timeIsRunning = true;
private void Start()
{
if (PlayerPrefs.HasKey("timeValue"))
{
remainingTime = PlayerPrefs.GetFloat("timeValue");
}
timerOn = true;
}
// Update is called once per frame
void Update()
{
if (remainingTime > 0)
{
remainingTime -= Time.deltaTime;
updateTimer(remainingTime);
PlayerPrefs.SetFloat("timeValue", remainingTime);
updateTimer(remainingTime);
}
else
{
remainingTime = 0;
timerOn = false;
}
void updateTimer(float DisplayTime)
{
DisplayTime -= 1;
int minutes = Mathf.FloorToInt(remainingTime / 60);
int seconds = Mathf.FloorToInt(remainingTime % 60);
timerText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
}
}
}
Okay so it is something to do with keeping the time value across scenes. It is something in this part of the code, I deleted this part just to see what would happen and it worked just fine.
private void Start()
{
if (PlayerPrefs.HasKey("timeValue"))
{
remainingTime = PlayerPrefs.GetFloat("timeValue");
}
timerOn = true;
}
So, I found that I am missing some correct way to delete the key when the timer hits zero or the scene or application is voided. But I have still not managed to get it right. I tried this,
void OnApplicationQuit()
{
PlayerPrefs.DeleteKey("timeValue");
}
and this
void resetTimer()
{
remainingTime = 0;
updateTimer(remainingTime);
PlayerPrefs.DeleteKey("timeValue");
}
Both were, of course, unsuccessful.
If you want it to persist across scenes, make it a DontDestroyOnLoad game object, rather than abusing PlayerPrefs.
Yeah that is something to try.
So far, I have not been able to get a simple DontDestroy script to work. I was watching tutorials and it said that this should work in a basic sense.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DontDestroy : MonoBehaviour
{
private void Awake()
{
DontDestroyOnLoad(gameObject);
}
}
Did you remember to put it on the correct game object?
I put it on the TMPro Text that the timer is on. I did get the timer to delete its key after zero by adding another if statement that I will show, but now the timer can only be reset if it hits zero rather than when the scene is quit with OnApplicationQuit. The DontDestroyOnLoad would be useful if it was working though. I could really use it for a scoring system that maintains score across scenes as each point gained switches to a new scene.
void Update()
{
if (remainingTime > 0)
{
remainingTime -= Time.deltaTime;
updateTimer(remainingTime);
PlayerPrefs.SetFloat("timeValue", remainingTime);
updateTimer(remainingTime);
}
else
{
remainingTime = 0;
timerOn = false;
}
if (remainingTime < 0)
{
remainingTime = 0;
updateTimer(remainingTime);
PlayerPrefs.DeleteKey("timeValue");
}
When I try:
void OnApplicationQuit()
{
PlayerPrefs.DeleteKey("timeValue");
it leaves the OnApplicationQuit greyed out and of course does nothing.
I tried this,
UnityEditor.EditorApplication.isPlaying = false;
PlayerPrefs.DeleteKey("timeValue");
and it deleted the key on application quit, but the scene quits on its own a second into beginning, so if I could figure out how to tell it that upon close delete the key that would work, but strangely void OnApplicationQuit() has not been working.
I was just putting void OnApplicationQuit into the wrong area of the script. It just worked. Now to try and get the DontDestroyonLoad to work for the score, I am set.
Yes you’ve been using local/nested methods in your script. I would avoid doing that unless you understand what you’re doing with them.
DontDestroyOnLoad does work and is a pretty fundamental part of Unity, so there is something you’re doing wrong on your end.
For time it seems straight forward enough. But for the score part, I found out my issue was that DontDestroyOnLoad only works if it is at root level on the scene and not under an object in a Canvas, which in order to have it at root level, the panel BG removes the text from sight. So, I am not sure if there is a work around for that or not. It would be nice if there was.