{"id":13662875,"url":"https://github.com/Mr-sB/UnityTimer","last_synced_at":"2025-04-25T11:30:38.646Z","repository":{"id":37766426,"uuid":"235527715","full_name":"Mr-sB/UnityTimer","owner":"Mr-sB","description":"Powerful and convenient library for running actions after a delay in Unity3D. Fork from akbiggs/UnityTimer. Add some useful functions.","archived":false,"fork":false,"pushed_at":"2025-01-13T04:24:04.000Z","size":131,"stargazers_count":52,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-07T03:14:14.428Z","etag":null,"topics":["delay","timer","unity3d-script"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mr-sB.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-22T08:15:36.000Z","updated_at":"2025-04-04T13:35:38.000Z","dependencies_parsed_at":"2022-09-17T03:11:23.076Z","dependency_job_id":null,"html_url":"https://github.com/Mr-sB/UnityTimer","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr-sB%2FUnityTimer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr-sB%2FUnityTimer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr-sB%2FUnityTimer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr-sB%2FUnityTimer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mr-sB","download_url":"https://codeload.github.com/Mr-sB/UnityTimer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250808046,"owners_count":21490612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["delay","timer","unity3d-script"],"created_at":"2024-08-02T05:02:10.750Z","updated_at":"2025-04-25T11:30:38.638Z","avatar_url":"https://github.com/Mr-sB.png","language":"C#","readme":"# Unity Timer\n\nRun actions after a delay in Unity3D.\n\nThis library has been battle-tested and hardened throughout numerous projects, including the award-winning [Pitfall Planet](http://pitfallplanet.com/).\n\nWritten by [Alexander Biggs](http://akbiggs.com) + [Adam Robinson-Yu](http://www.adamgryu.com/).\n\nFork by GH-ZJ(wustzhangjie@gmail.com)\n\n## Basic Example\n\nThe Unity Timer package provides the following method for creating timers:\n```c#\npublic static DelayTimer DelayAction(float duration, Action onComplete, Action\u003cfloat\u003e onUpdate = null, bool useRealTime = false, Object autoDestroyOwner = null);\n\npublic static DelayFrameTimer DelayFrameAction(int frame, Action onComplete, Action\u003cfloat\u003e onUpdate = null, Object autoDestroyOwner = null);\n\npublic static LoopTimer LoopAction(float interval, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n        \npublic static LoopUntilTimer LoopUntilAction(float interval, Func\u003cLoopUntilTimer, bool\u003e loopUntil, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n\npublic static LoopCountTimer LoopCountAction(float interval, int loopCount, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n\npublic static DelayTimer PersistenceDelayAction(float duration, Action onComplete, Action\u003cfloat\u003e onUpdate = null, bool useRealTime = false, Object autoDestroyOwner = null);\n\npublic static DelayFrameTimer PersistenceDelayFrameAction(int frame, Action onComplete, Action\u003cfloat\u003e onUpdate = null, Object autoDestroyOwner = null);\n\npublic static LoopTimer PersistenceLoopAction(float interval, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n\npublic static LoopUntilTimer PersistenceLoopUntilAction(float interval, Func\u003cLoopUntilTimer, bool\u003e loopUntil, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n\npublic static LoopCountTimer PersistenceLoopCountAction(float interval, int loopCount, Action\u003cint\u003e onComplete, Action\u003cfloat\u003e onUpdate = null, Action onFinished = null, bool useRealTime = false, bool executeOnStart = false, Object autoDestroyOwner = null);\n```\n## Motivation\n\nOut of the box, without this library, there are two main ways of handling timers in Unity:\n\n1. Use a coroutine with the WaitForSeconds method.\n2. 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 \u003e= timerDuration`.\n\nThe 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](http://docs.unity3d.com/ScriptReference/Time-timeScale.html).\n\nThe second method is error-prone, and hides away the actual game logic that you are trying to express.\n\nThis library alleviates both of these concerns, making it easy to add an easy-to-read, expressive timer to any class in your Unity project.\n\n## Features\n\n* Make a timer repeat by call Timer.LoopAction.\n```c#\nprivate void Start()\n{\n   Timer.LoopAction(5, loopTime =\u003e { Debug.LogError(\"Timer Called: \" + loopTime); });\n}\n```\n\n* Make a loop timer execute when start by setting `executeOnStart` to true.\n```c#\nprivate void Start()\n{\n   Timer.LoopAction(5, loopTime =\u003e { Debug.LogError(\"Timer Called: \" + loopTime); }, executeOnStart: true);\n}\n```\n\n* Make a timer based on frame count by call Timer.DelayFrameAction.\n```c#\nprivate void Start()\n{\n   Timer.DelayFrameAction(5, () =\u003e { Debug.LogError(\"Timer Called\"); });\n}\n```\n\n* Measure time by [realtimeSinceStartup](http://docs.unity3d.com/ScriptReference/Time-realtimeSinceStartup.html)\n  instead of scaled game time by setting [Obsolete(\"Use updateMode to instead.\")]`useRealTime` to true.\n  Default is false.\n```c#\nprivate void Start()\n{\n   Timer.DelayAction(5, () =\u003e { Debug.LogError(\"Timer Called\"); }, useRealTime: true);\n}\n```\n\n* Measure time by [time](http://docs.unity3d.com/ScriptReference/Time-time.html) or [unscaledTime](http://docs.unity3d.com/ScriptReference/Time-unscaledTime.html) or [realtimeSinceStartup](http://docs.unity3d.com/ScriptReference/Time-realtimeSinceStartup.html)\n  by setting `updateMode` to `Timer.UpdateMode.GameTime` or `Timer.UpdateMode.UnscaledGameTime` or `Timer.UpdateMode.RealTime`.\n  Default is `Timer.UpdateMode.GameTime`.\n```c#\nprivate void Start()\n{\n   Timer.DelayAction(5, () =\u003e { Debug.LogError(\"Timer Called\"); }, null, Timer.UpdateMode.UnscaledGameTime);\n}\n```\n\n* Cancel a timer after calling it.\n```c#\nTimer timer;\n\nvoid Start() {\n   timer = Timer.LoopAction(5, _ =\u003e { Debug.LogError(\"Timer Called\"); });\n}\n\nvoid Update() {\n   if (Input.GetKeyDown(KeyCode.X)) {\n      Timer.Cancel(timer);\n   }\n}\n```\n\n* 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.\n\nVery 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.\n```c#\npublic class CoolMonoBehaviour : MonoBehaviour {\n\n   private void Start()\n   {\n      //The timer will cancel when the Component is destroyed;\n      Timer.DelayAction(5, () =\u003e { Debug.LogError(\"Timer Called\"); }, useRealTime: true, autoDestroyOwner: this);\n   }\n\n   private void Update()\n   {\n      // This code could destroy the object at any time!\n      if (Input.GetKeyDown(KeyCode.X)) {\n         GameObject.Destroy(this.gameObject);\n      }\n   }\n}\n```\n\n* Update a value gradually over time using the `onUpdate` callback.\n\n```c#\n// Change a color from white to red over the course of five seconds.\nColor color = Color.white;\nfloat transitionDuration = 5f;\n\nTimer.DelayAction(transitionDuration,\n   onUpdate: secondsElapsed =\u003e color.r = 255 * (secondsElapsed / transitionDuration),\n   onComplete: () =\u003e Debug.Log(\"Color is now red\"));\n```\n\n* A number of other useful features are included!\n\n- `timer.Pause()`\n- `timer.Resume()`\n- `timer.Cancel()`\n- `timer.Restart()`\n- `timer.GetTimeElapsed()`\n- `timer.GetTimeRemaining()`\n- `timer.GetRatioComplete()`\n- `timer.isDone`\n- `Timer.CancelAllRegisteredTimers()`\n- `Timer.CancelAllRegisteredTimersByOwner(owner)`\n- `Timer.PauseAllRegisteredTimers()`\n- `Timer.ResumeAllRegisteredTimers()`\n\n* Make a timer not effect by `Timer.XXXAllRegisteredTimers()` function by call `Timer.PersistenceXXX()` function.\n```c#\nTimer timer;\n\nvoid Start() {\n   //The timer will not cancel when Timer.XXXAllRegisteredTimers();\n   timer = Timer.PersistenceLoopAction(5, _ =\u003e { Debug.LogError(\"Timer Called\"); });\n}\n\nvoid Update() {\n   //No effect to timer\n   if (Input.GetKeyDown(KeyCode.X))\n      Timer.CancelAllRegisteredTimers();\n\n   //Only this can cancel persistence timer\n   if(Input.GetKeyDown(KeyCode.C))\n      Timer.Cancel(timer);//same to timer?.Cancel();\n}\n```\n\n* 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.\n```c#\nvoid Start() {\n   //The timer will attach to the Component instance.\n   this.DelayAction(5, () =\u003e { Debug.LogError(\"Timer Called\"); });\n}\n```\n\n\n* A test scene + script demoing all the features is included with the package in the `/Example` folder.\n\n## Usage Notes / Caveats\n* All timers will not destroy when change scene, because TimerManager is `DontDestroyOnLoad`.\n","funding_links":[],"categories":["C\\#"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMr-sB%2FUnityTimer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMr-sB%2FUnityTimer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMr-sB%2FUnityTimer/lists"}