As mentioned you should make it a singleton (meaning only one instance should exist at a time - not speaking about the general (ab)use of having a public static reference ;) )
And use DontDestroyOnLoad
in order to keep your object also when the scene is changed and for the resetting use SceneManager.sceneLoaded
and check the index of the newly loaded scene like e.g.
public class Timer : MonoBehaviour
{
// Make sure this text is also not destroyed
// e.g. make its entire canvas a child of this object
public Text TimerText;
public bool shouldCountTime;
public float t;
// Singleton Pattern -> make sure only one instance exists in your scene
private static Timer _instance;
private void Awake()
{
// does another instance already exist?
if(_instance && _instance != this)
{
// if so detroy this one
Destroy(gameObject);
return;
}
// This is the active instance
_instance = this;
// Don't destroy this GameObject when a new scene is loaded
DontDestroyOnload(gameObject);
// Attach a callback for every new scene that is loaded
// It is fine to remove a callback that wasn't added so far
// This makes sure that this callback is definitely only added once
// usually I do this only as a kind of convention
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneLoaded += OnSceneLoaded;
}
// Will be called every time a scene is loaded
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// check the build index
shouldCountTime = scene.buildIndex != 0;
// Reset in the main menu
if(!shouldCountTime)
{
Debug.Log("Reset timer", this);
t = 0;
TimerText.text = "0:00";
}
}
private void OnDestroy()
{
// Even though your object most probably lives during the entire application lifetime
// again just as a convention always remove callbacks as soon as not needed anymore
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void Update()
{
// do your calculations only while the value is actually changing
if (!shouldCountTime) return;
t += Time.deltaTime;
var minutes = ((int)t / 60).ToString();
var seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
If changing the hierarchy (regarding e.g. the Text) is not an option than rather refer to How to pass data between scenes in Unity for alternative solutions for caring over the value.