{"id":13663708,"url":"https://github.com/akbiggs/UnityTimer","last_synced_at":"2025-04-25T17:32:37.721Z","repository":{"id":41308884,"uuid":"48929874","full_name":"akbiggs/UnityTimer","owner":"akbiggs","description":"Powerful and convenient library for running actions after a delay in Unity3D.","archived":false,"fork":false,"pushed_at":"2021-06-02T04:06:36.000Z","size":108,"stargazers_count":936,"open_issues_count":10,"forks_count":120,"subscribers_count":40,"default_branch":"master","last_synced_at":"2024-11-10T20:38:16.267Z","etag":null,"topics":[],"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/akbiggs.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":"2016-01-03T01:23:37.000Z","updated_at":"2024-11-09T10:18:45.000Z","dependencies_parsed_at":"2022-07-18T08:13:31.641Z","dependency_job_id":null,"html_url":"https://github.com/akbiggs/UnityTimer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akbiggs%2FUnityTimer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akbiggs%2FUnityTimer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akbiggs%2FUnityTimer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akbiggs%2FUnityTimer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akbiggs","download_url":"https://codeload.github.com/akbiggs/UnityTimer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250862175,"owners_count":21499237,"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":[],"created_at":"2024-08-02T05:02:34.942Z","updated_at":"2025-04-25T17:32:37.710Z","avatar_url":"https://github.com/akbiggs.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.xyz) + [Adam Robinson-Yu](http://www.adamgryu.com/).\n\n### Installation\n\nTo get the latest release of UnityTimer, head over to [the Releases page](https://github.com/akbiggs/UnityTimer/releases) and download the Timer.unitypackage file from the latest release. Then if you have a Unity project open, you can open the .unitypackage file to install the scripts into your project.\n\nAlternatively, if you like to live on the bleeding edge, add `https://github.com/akbiggs/UnityTimer.git` to your packages in Unity Package Manager. However, we do not guarantee this will give you a stable version.\n\n![Screenshot of selecting add git URL](https://i.imgur.com/Crx5hnZ.png)\n![Screenshot of adding package to UPM](https://i.imgur.com/IW4b6a8.png)\n\n### Basic Example\n\nThe Unity Timer package provides the following method for creating timers:\n\n```c#\n/// \u003csummary\u003e\n/// Register a new timer that should fire an event after a certain amount of time\n/// has elapsed.\n/// \u003c/summary\u003e\n/// \u003cparam name=\"duration\"\u003eThe time to wait before the timer should fire, in seconds.\u003c/param\u003e\n/// \u003cparam name=\"onComplete\"\u003eAn action to fire when the timer completes.\u003c/param\u003e\npublic static Timer Register(float duration, Action onComplete);\n```\n\nThe method is called like this:\n\n```c#\n// Log \"Hello World\" after five seconds.\n\nTimer.Register(5f, () =\u003e Debug.Log(\"Hello World\"));\n```\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 setting `isLooped` to true.**\n\n```c#\n// Call the player's jump method every two seconds.\n\nTimer.Register(2f, player.Jump, isLooped: true);\n```\n\n**Cancel a timer after calling it.**\n\n```c#\nTimer timer;\n\nvoid Start() {\n   timer = Timer.Register(2f, () =\u003e Debug.Log(\"You won't see this text if you press X.\"));\n}\n\nvoid Update() {\n   if (Input.GetKeyDown(KeyCode.X)) {\n      Timer.Cancel(timer);\n   }\n}\n```\n\n**Measure time by [realtimeSinceStartup](http://docs.unity3d.com/ScriptReference/Time-realtimeSinceStartup.html) instead of scaled game time by setting `useRealTime` to true.**\n\n```c#\n// Let's say you pause your game by setting the timescale to 0.\nTime.timeScale = 0f;\n\n// ...Then set useRealTime so this timer will still fire even though the game time isn't progressing.\nTimer.Register(1f, this.HandlePausedGameState, useRealTime: true);\n```\n\n**Attach the timer to a MonoBehaviour so that the timer is destroyed when the MonoBehaviour is.**\n\nVery often, a timer called from a MonoBehaviour will manipulate that behaviour's state. Thus, it is common practice to cancel the timer in the OnDestroy method of the MonoBehaviour. We've added a convenient extension method that attaches a Timer to a MonoBehaviour such that it will automatically cancel the timer when the MonoBehaviour is detected as null.\n\n```c#\npublic class CoolMonoBehaviour : MonoBehaviour {\n\n   void Start() {\n      // Use the AttachTimer extension method to create a timer that is destroyed when this\n      // object is destroyed.\n      this.AttachTimer(5f, () =\u003e {\n      \n         // If this code runs after the object is destroyed, a null reference will be thrown,\n         // which could corrupt game state.\n         this.gameObject.transform.position = Vector3.zero;\n      });\n   }\n   \n   void Update() {\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.Register(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.GetTimeRemaining()\n- timer.GetRatioComplete()\n- timer.isDone\n\nA test scene + script demoing all the features is included with the package in the `Timer/Example` folder.\n\n## Usage Notes / Caveats\n\n1. All timers are destroyed when changing scenes. This behaviour is typically desired, and it happens because timers are updated by a TimerController that is also destroyed when the scene changes. Note that as a result of this, creating a Timer when the scene is being closed, e.g. in an object's OnDestroy method, will [result in a Unity error when the TimerController is spawned](http://i.imgur.com/ESFmFDO.png).\n","funding_links":[],"categories":["Open Source Repositories","C\\#","C#","Open Source Packages"],"sub_categories":["Utilities"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakbiggs%2FUnityTimer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakbiggs%2FUnityTimer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakbiggs%2FUnityTimer/lists"}