Posts Tagged CSharp

Timer Manager for Unity3D

It’s been a nearly a month since my last blog entry. Typically people disappear for long periods of time because they’ve either just begun a romantic charade or they just became insanely busy with work. Well in my case, I’m already happily married with a sweet little daughter so it’s clearly a work issue. If you haven’t guessed it yet from this site, I’m actually starting a new company named Monkey Prism. At Monkey Prism we’re in the midst of an up and coming Unity 3D iOS release. During our development cycle we were in need of a basic timer object. This example really serves as an object to learn from on how to use Time.time in your code to create a basic timer. Feel free to use this code in anyway that you like!

Here is how you call this MPTimer object.
Example 1

View Code CSHARP
//Example 1:
private MPTimer monkeyPrismTimer;
 
void Start() {
   /*
   Creates a timer object that will wait 5 seconds before calling 
   the ToggleExample method.  The false flag signifies that this object
   will not start the timer until the 
      monkeyPrismTimer.Active = true;
   has been set.
   */
   monkeyPrismTimer = new MPTimer(
      new MPTimerObject(gameObject, "ToggleExample", 5.0f), false);
}
 
public void ToggleExample() {
   Debug.Log("ToggleExample() called!");
}
 
void Update() {
   //daisy chain the timer running.  Every time it inactivates, we'll re-activate it.
   if (!monkeyPrismTimer.Active) {
      Debug.Log("Enabling the timer!");
      monkeyPrismTimer.Active = true;
   }
 
   //drive the timer
   monkeyPrismTimer.DoTimer();
}

Example 2 (auto-start the timer)

View Code CSHARP
private MPTimer monkeyPrismTimer;
 
void Start() {
   //create a 3 second timer that repeats 10 times.
   MPTimerObject mpTimerObject = new MPTimerObject(gameObject, "ToggleExample", 3.0f);
   mpTimerObject.repeatCount = 10;  // repeat it 10 times.
 
   //creates a timer object without auto-starting it.
   monkeyPrismTimer = new MPTimer(mpTimerObject, true);
}
 
public void ToggleExample() {
   Debug.Log("ToggleExample() called!");
}
 
void Update() {
   //drive the timer
   monkeyPrismTimer.DoTimer();
}

The file on my system is named: “MPTimer.cs“. Here it is! The meat and potatoes we’ve been talking about!

Download MPTimer.cs
using System;
using UnityEngine;
 
/// <summary>
/// A timer object that will be passed into the MPTimer class.
/// </summary>
public class MPTimerObject
{
	/// <summary>
	/// The target GameObject that contains the onCompleteMethod specified.
	/// </summary>
	public GameObject target;
	/// <summary>
	/// A string representing the method to call when the timer expires.
	/// </summary>
	public String onCompleteMethod;
	/// <summary>
	/// A float value in seconds representing how often you would like the timer to trigger.
	/// </summary>
	public float runForSeconds;
	/// <summary>
	/// An integer value representing the number of times you would like this timer to trigger before becoming inactive.
	/// </summary>
	public int repeatCount;
 
	public MPTimerObject() { }
 
	/// <summary>
	/// Creates a basic Monkey Prism timer object.
	/// </summary>
	/// <param name="targetCompleteMethodObject">
	/// A <see cref="GameObject"/> that is the targeted object that contains the "completeMethod" string parameter.
	/// </param>
	/// <param name="completeMethod">
	/// A <see cref="String"/> representing a method named contained within the GameObject specified.  Example:  "myMethod"
	/// </param>
	/// <param name="triggerTime">
	/// A <see cref="System.Single"/> float value in seconds.  5.0f would be 5 seconds.  This tells the timer to trigger in 5 seconds.
	/// </param>
	public MPTimerObject(GameObject targetCompleteMethodObject, String completeMethod, float triggerTime)
	{
		Init(targetCompleteMethodObject, completeMethod, triggerTime, 1);
	}
 
	private void Init(GameObject targetCompleteMethodObject, String completeMethod, float runForSeconds, int repeatCount)
	{
		this.target = targetCompleteMethodObject;
		onCompleteMethod = completeMethod;
		this.runForSeconds = runForSeconds;
		this.repeatCount = repeatCount;
	}
}
 
/// <summary>
/// A Monkey Prism timer object that allows for a user to trigger a method based on a time specified.
/// </summary>
public class MPTimer
{
	private MPTimerObject timerObject;
	private float startTime;
	private float endTime;
	private bool active;
	private int count;
 
	/// <summary>
	/// Create a new MPTimer object.
	/// </summary>
	/// <param name="mpTimerObject">
	/// A <see cref="MPTimerObject"/>
	/// </param>
	public MPTimer(MPTimerObject mpTimerObject)
	{
		Init(mpTimerObject, true);
	}
 
	/// <summary>
	/// Create a new MPTimer object.
	/// </summary>
	/// <param name="mpTimerObject">
	/// A <see cref="MPTimerObject"/>
	/// </param>
	/// <param name="activeState">
	/// A <see cref="System.Boolean"/> representing whether to start the timer immediately or to wait.  If true, the timer will kick-off immediately.
	/// </param>
	public MPTimer(MPTimerObject mpTimerObject, bool activeState)
	{
		Init(mpTimerObject, activeState);
	}
 
	private void Init(MPTimerObject mpTimerObject, bool activeState)
	{
		if (mpTimerObject == null || 
		    mpTimerObject.onCompleteMethod == null || mpTimerObject.target == null) {
			Debug.LogError("MPTimer Error: Invalid MPTimerObject specified.");
		}
		timerObject = mpTimerObject;
		Active = activeState;
	}
 
	/// <summary>
	/// The MPTimerObject get/set helper.  Setting a new timer object will inactivate the current timer.
	/// </summary>
	public MPTimerObject TimerObject
	{
		get { return timerObject; }
		set {
			active = false;
			timerObject = value;
		}
	}
 
	/// <summary>
	/// The Active get/set helper.  By setting this to "Active" you will instantly cause this method to be called.
	/// </summary>
	public bool Active
	{
		get { return active; }
		set { 
			if (value != active) 
				count = 0;
			active = value; 
			if (active) {
				startTime = Time.time;
				endTime = startTime + timerObject.runForSeconds;
				//Debug.Log("Start= " + startTime + ", End= " + endTime);
			}
		}
	}
 
	/// <summary>
	/// A method used for the "Update" call in your calling library.  If this method is not called, the timer is not automatically driven.
	/// </summary>
	public void DoTimer()
	{
		if (!active) return;
 
		if (Time.time >= endTime) {
			//Debug.Log("timer fired!");
			timerObject.target.SendMessage(timerObject.onCompleteMethod);
			if (++count >= timerObject.repeatCount)
				active = false; //toggle off.
		}
	}
}

, , , , ,

No Comments