Giter Club home page Giter Club logo

unitytimer's Introduction

Unity Timer

Run actions after a delay in Unity3D.

This library has been battle-tested and hardened throughout numerous projects, including the award-winning Pitfall Planet.

Written by Alexander Biggs + Adam Robinson-Yu.

Fork by GH-ZJ([email protected])

Basic Example

The Unity Timer package provides the following method for creating timers:

public static DelayTimer DelayAction(float duration, Action onComplete, Action<float> onUpdate = null, bool useRealTime = false, Object autoDestroyOwner = null);

public static DelayFrameTimer DelayFrameAction(int frame, Action onComplete, Action<float> onUpdate = null, Object autoDestroyOwner = null);

public static LoopTimer LoopAction(float interval, Action<int> onComplete, Action<float> onUpdate = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);
        
public static LoopUntilTimer LoopUntilAction(float interval, Func<LoopUntilTimer, bool> loopUntil, Action<int> onComplete, Action<float> onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);

public static LoopCountTimer LoopCountAction(float interval, int loopCount, Action<int> onComplete, Action<float> onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);

public static DelayTimer PersistenceDelayAction(float duration, Action onComplete, Action<float> onUpdate = null, bool useRealTime = false, Object autoDestroyOwner = null);

public static DelayFrameTimer PersistenceDelayFrameAction(int frame, Action onComplete, Action<float> onUpdate = null, Object autoDestroyOwner = null);

public static LoopTimer PersistenceLoopAction(float interval, Action<int> onComplete, Action<float> onUpdate = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);

public static LoopUntilTimer PersistenceLoopUntilAction(float interval, Func<LoopUntilTimer, bool> loopUntil, Action<int> onComplete, Action<float> onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);

public static LoopCountTimer PersistenceLoopCountAction(float interval, int loopCount, Action<int> onComplete, Action<float> onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);

Motivation

Out of the box, without this library, there are two main ways of handling timers in Unity:

  1. Use a coroutine with the WaitForSeconds method.
  2. Store the time that your timer started in a private variable (e.g. startTime = Time.time), then check in an Update call if Time.time - startTime >= timerDuration.

The first method is verbose, forcing you to refactor your code to use IEnumerator functions. Furthermore, it necessitates having access to a MonoBehaviour instance to start the coroutine, meaning that solution will not work in non-MonoBehaviour classes. Finally, there is no way to prevent WaitForSeconds from being affected by changes to the time scale.

The second method is error-prone, and hides away the actual game logic that you are trying to express.

This library alleviates both of these concerns, making it easy to add an easy-to-read, expressive timer to any class in your Unity project.

Features

  • Make a timer repeat by call Timer.LoopAction.
private void Start()
{
   Timer.LoopAction(5, loopTime => { Debug.LogError("Timer Called: " + loopTime); });
}
  • Make a loop timer execute when start by setting executeOnStart to true.
private void Start()
{
   Timer.LoopAction(5, loopTime => { Debug.LogError("Timer Called: " + loopTime); }, executeOnStart: true);
}
  • Make a timer based on frame count by call Timer.DelayFrameAction.
private void Start()
{
   Timer.DelayFrameAction(5, () => { Debug.LogError("Timer Called"); });
}
  • Measure time by realtimeSinceStartup instead of scaled game time by setting [Obsolete("Use updateMode to instead.")]useRealTime to true. Default is false.
private void Start()
{
   Timer.DelayAction(5, () => { Debug.LogError("Timer Called"); }, useRealTime: true);
}
  • Measure time by time or unscaledTime or realtimeSinceStartup by setting updateMode to Timer.UpdateMode.GameTime or Timer.UpdateMode.UnscaledGameTime or Timer.UpdateMode.RealTime. Default is Timer.UpdateMode.GameTime.
private void Start()
{
   Timer.DelayAction(5, () => { Debug.LogError("Timer Called"); }, null, Timer.UpdateMode.UnscaledGameTime);
}
  • Cancel a timer after calling it.
Timer timer;

void Start() {
   timer = Timer.LoopAction(5, _ => { Debug.LogError("Timer Called"); });
}

void Update() {
   if (Input.GetKeyDown(KeyCode.X)) {
      Timer.Cancel(timer);
   }
}
  • Attach the timer to a UnityEngine.Object by setting autoDestroyOwner to the UnityEngine.Object, so that the timer is destroyed when the UnityEngine.Object is.

Very often, a timer called from a Component will manipulate that component's state. Thus, it is common practice to cancel the timer in the OnDestroy method of the Component. We've added a convenient extension method that attaches a Timer to a Component such that it will automatically cancel the timer when the Component is detected as null.

public class CoolMonoBehaviour : MonoBehaviour {

   private void Start()
   {
      //The timer will cancel when the Component is destroyed;
      Timer.DelayAction(5, () => { Debug.LogError("Timer Called"); }, useRealTime: true, autoDestroyOwner: this);
   }

   private void Update()
   {
      // This code could destroy the object at any time!
      if (Input.GetKeyDown(KeyCode.X)) {
         GameObject.Destroy(this.gameObject);
      }
   }
}
  • Update a value gradually over time using the onUpdate callback.
// Change a color from white to red over the course of five seconds.
Color color = Color.white;
float transitionDuration = 5f;

Timer.DelayAction(transitionDuration,
   onUpdate: secondsElapsed => color.r = 255 * (secondsElapsed / transitionDuration),
   onComplete: () => Debug.Log("Color is now red"));
  • A number of other useful features are included!
  • timer.Pause()
  • timer.Resume()
  • timer.Cancel()
  • timer.Restart()
  • timer.GetTimeElapsed()
  • timer.GetTimeRemaining()
  • timer.GetRatioComplete()
  • timer.isDone
  • Timer.CancelAllRegisteredTimers()
  • Timer.CancelAllRegisteredTimersByOwner(owner)
  • Timer.PauseAllRegisteredTimers()
  • Timer.ResumeAllRegisteredTimers()
  • Make a timer not effect by Timer.XXXAllRegisteredTimers() function by call Timer.PersistenceXXX() function.
Timer timer;

void Start() {
   //The timer will not cancel when Timer.XXXAllRegisteredTimers();
   timer = Timer.PersistenceLoopAction(5, _ => { Debug.LogError("Timer Called"); });
}

void Update() {
   //No effect to timer
   if (Input.GetKeyDown(KeyCode.X))
      Timer.CancelAllRegisteredTimers();

   //Only this can cancel persistence timer
   if(Input.GetKeyDown(KeyCode.C))
      Timer.Cancel(timer);//same to timer?.Cancel();
}
  • All timer generator functions can shortcut call by using Component/GameObject Extensions functions, and the timer will attach to the Component/GameObject so that the timer is destroyed when the Component/GameObject is.
void Start() {
   //The timer will attach to the Component instance.
   this.DelayAction(5, () => { Debug.LogError("Timer Called"); });
}
  • A test scene + script demoing all the features is included with the package in the /Example folder.

Usage Notes / Caveats

  • All timers will not destroy when change scene, because TimerManager is DontDestroyOnLoad.

unitytimer's People

Contributors

mr-sb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.