How To reset a timer if using a Time.timeSinceLevelLoad

Hi guys my first post here so im hoping i have given enough information on this post

My question is im making a tile match game in c# in unity i have everything made up but when i run out of time i.e. a game over function when i go to replay the game the timer Time.timeSinceLevelLoad has already been counting and already counted past the 0 time mark so it keeps setting off the game over function. - main area of error is lines 65 to 80 this is where the timer gets changed and edited to allow for aditional time when a match is given or a wrong match is lost (adjustTime), keepSeconds sends a time to keep for the score board results.

here is my code for my timer sorry there is alot of commenting and comment out of functions its for a uni project and they require me to put alot in. if you want to try this code to see hot the timer counts down atm, just add it to a empty game object and do a UI slider and place the slider into the slider request in the required spot in the inspector.

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

public class Timer : MonoBehaviour 
{
	private Text timeText; //if i want the time displayed in text
	private float startTime = 120f; // sets how much time the player has to start with
	private float startWith;
	public static float Seconds;
	public static float keepSeconds;
	//private float roundedSeconds;
	//private string txtSeconds;
	//private string txtminutes;
	public static int countSeconds;
	/*
	changed bellow line to go from a private to public static so i can trigger the timer on and off
	with the TileGenerator script in the matchTwo card section lines 102, 105, 119 and 124.
	
	**UPDATE**
		Changed it back to the private as this function was not working as intended as the timer once 
		it goes back Time.time over rides what i was wanting to happen.. Fix bellow 
	*/ 
	public static bool stopTimer = false;
	/* timer to add and subtract time need to pull the Time.time into a float var so you can change
	*/ 
	private float adjustTime = 0; // sets the adjustTime back to 0 so it dosnt take on previouse tries at the game
	public static int timeAdjustBy = 5; // how much to add or take time from\
	public Slider timerBarSlider;  //reference for slider
	public float playerTime = 0f;
	public float guiTime;
	public static float timeOnLevel;

	// Use this for initialization
	void Awake () 
	{
		startTime = 120f;
		startWith = startTime;
		timeText = gameObject.GetComponent<Text> ();
		timerBarSlider.maxValue = startWith; // sets how much time is displayed on the bar when full i.e. 120
		timerBarSlider.minValue = 0; // sets the lowest amount of the slider i.e. 0 = end of time
		timerBarSlider.wholeNumbers = false; // allows the timer to slide down instead of jumping around
	}
	// Update is called once per frame
	void Update () 
	{

		if (stopTimer == false) // runs only while the bool for stopTimer is false which its auto set to above in the declaring
		{

			if (Seconds >= startTime) // if the seconds is greater than or equal to the start time i.e. 120 then run this
			{
				adjustTime -= 5f;// was some how giving a +5 to the seconds so by taking this off i have adjusted that error
				Seconds = startWith;
			}
			adjustTime = (float)countSeconds;// adjusts the time according to if a correct answer or wrong answer given.
			// the (float) converts it from a int to a float so it can change the time accordingly
			//float guiTime = Time.time - startTime; //original line

			/*
			 * The line bellow is starting the timer from the start of the scene loading up
			 * as i had a problem the timer was actually running from once you loaded the menu
			 * or starting of the game this little change also helped with the restarting
			 * of the level as it reset the timer back to what it should have been
			 * */
			//guiTime = Time.timeSinceLevelLoad - startTime; //takes 120 and subtracts the time since level loaded
			guiTime = Time.timeSinceLevelLoad - startTime; //takes 120 and subtracts the time since level loaded
			Seconds = adjustTime - (guiTime); // Seconds = the time above ie 120 - Time since level loaded and takes any time i have given or taken off to adjust the time
			keepSeconds = Time.timeSinceLevelLoad - adjustTime;
		}

		if (Seconds <= 0) // if the time = 0 or less then the game is over and the player looses run this loop
		{

			playerTime = guiTime;
			Debug.Log ("The timer is over!"); // sends a message to teh debug console
			Application.LoadLevel ("timeUp"); // load this level upon end of game
			stopTimer = true; // stops the timer and there for the top if loop
		}

		/*/DISPLAY TIMER
		roundedSeconds = Mathf.CeilToInt (Seconds);
		txtSeconds = (roundedSeconds % 60f).ToString("00");
		txtminutes = (roundedSeconds / 120f).ToString("00");
		timeText.text = "Remaining Time: " + txtminutes + ":" + txtSeconds; // Added in the : to seperate the Mins from the seconds
		*///Debug.Log ("Remaining Time: " + txtminutes + txtSeconds);

		//Timer Slider Bar
		timerBarSlider.value = Seconds;
	}

}

i’m just wondering if there is a way to reset the timer ((Time.timeSinceLevelLoad) or a work around i can do. but what i can only see is its a read only and you cant reset it… unless i have missed something) so when the game is run from the menu scene with out quitting the game and restarting it? or would i be best off making my own timer and how would i do this just making my own timer thing i can work out what functions to rename etc if someone just puts in a sample code or something in a comment.

Aim of the level sequences

WIN

  • Menu → (click start) loads level → (Matched all the pairs) congratulations sceen → Menu scene → replay level(start) ( timer dosnt reset runs off what is left - need to fix)

Loose

  • Menu → (click start) loads level → (Time Ran out) game over scene → Menu scene → replay level(start) ( timer dosn’t reset runs off what is left - need to fix)

Things i have tried

  • Time.time.SinceLevelLoad = 0
  • a float taking the time and deducting the time already played
  • Making my own timer ( didn’t have success in this one - never counted and don’t know why)
  • keeping the time in a don’t destroy object to deduct from Time.timeSinceLevelLoaded ( timer stopped working on this as it continuously reset the timer back to 120 ( playable time))
  • have done a Debug.Log in the timer to get it to print the time
  • placed the script on a timerManager which is a empty game object

Thank you again in advance

regards Mykel (Michael) Williams.

First of all, your file is quite bloated with things you do not need for your timer and which complicate understanding your code. I think just the essential code without changelogs and variables in comments would be much easier to read.

Second: There is no “clean” way to reset Time.timeSinceLevelLoad except for reloading the whole scene. You propably do not want that…

Third: Since you are going for static variables, let’s go the whole way: Use a Singleton. In case you are not aware: A Singleton is a class that has a single, static instance that can be accessed from where you want. Singletons usually prevent multiple Instances by making their constructor private and calling it from a static getter method that checks for an already existing instance. In Unity, you have to delete the surplus of Instances. A code for a timer singleton with basic functionality looks like this:

 using UnityEngine;
 using System.Collections;
 
 public class Timer : MonoBehaviour 
 {
	// Static Instance of this Timer (since you seem to want a single Timer)
	private static Timer m_instance;
	 
    private float m_startTime; // sets how much time the player has to start with
	private float m_timePassed;
	 
	public float RemainingSeconds;
 
    public bool IsTicking;

 
    // Use this for initialization
    void Awake () 
    {
		// Another timer exists, kill this one
		if(m_instance != null && m_instance != this)
		{
			Destroy(this);
		}
		else
		{
			// assign Singleton
			m_instance = this;
		}
		
		// Init Timer
		m_startTime = 120f;
		m_timePassed = 0f;
		
		RemainingSeconds = startTime;
		
		IsTicking = true;
    }

    //Update is called once per frame
    void Update () 
    {
		
        if (IsTicking) // already a bool no check for true needed
        {
			// add frame time to passed time
			m_timePassed += Time.deltaTime;
			
			RemainingSeconds = m_startTime - m_timePassed;
		
			// Clamp time to start time
			if (RemainingSeconds >= m_startTime)
            {
				RemainingSeconds = m_startTime;
            } 
			
			// No time left
			if(RemainingSeconds <= 0)
			{
				// This is Game Over
				RemainingSeconds = 0;
				m_stopTimer = true;
				return;
			}
        }
    }
	
	// Use this Method to access your timer
	public static Timer Get()
	{
		// failsafe
		if(m_instance = null)
		{
			GameObject go = new GameObject();
			m_instance = go.AddComponent<Timer>();
		}
		return m_instance;
	}
	
	// Reset your time
	public void ResetTimer()
	{
		m_timePassed = 0;
	}
	
	// If you want to substract time, use a negative value
	public void AddTime(float _seconds)
	{
		m_timePassed -= _seconds;
	}
 }

So if you want to know your remaining time you call Timer.Get().RemainingSeconds; and to reset your timer, call Timer.Get().ResetTimer();

On a side note: You do not need to explicitly cast an int into a float. This cast works implicitly :).