Class Timer
A general-purpose timer that tracks elapsed time and invokes callbacks on completion. Supports pausing, resuming, looping, time scaling, and provides progress information. All control methods return the timer instance for fluent method chaining.
Inherited Members
Namespace: Scylla.Core.Util
Assembly: ScyllaCore.dll
Syntax
public sealed class Timer
Remarks
This timer requires manual updates via the Update(float) method and does not
update automatically. It is fully decoupled from Unity's Time system - callers
are responsible for supplying an appropriate delta time each frame (e.g.
Time.deltaTime, a fixed delta, or a scaled variant).
Use the Create(float, Action) and CreateLooping(float, Action) factory methods for
the most convenient construction. All state-mutation methods return this to
support fluent chaining, for example:
var timer = Timer.Create(2f, OnDone).Start();
Constructors
Timer(float)
Creates a new Timer instance with the specified duration.
Declaration
public Timer(float duration = 1)
Parameters
| Type | Name | Description |
|---|---|---|
| float | duration | The duration of the timer in seconds. Default is 1.0. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if duration is negative. |
Properties
Duration
Gets or sets the total duration of one timer cycle, in seconds. Must be greater than or equal to zero.
Declaration
public float Duration { get; set; }
Property Value
| Type | Description |
|---|---|
| float |
Remarks
Changing this value while the timer is running takes effect immediately and will affect both RemainingTime and Progress on the next access. If the current ElapsedTime already exceeds the new duration, the timer will complete on the next Update(float) call.
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if value is negative. |
ElapsedTime
Gets the elapsed time since the timer was started, in seconds.
Declaration
public float ElapsedTime { get; }
Property Value
| Type | Description |
|---|---|
| float |
IsComplete
Gets a value indicating whether the timer has completed its full duration.
Returns false when Duration is zero, because a zero-duration
timer completes and stops inside the first Update(float) call rather than
through normal elapsed-time accumulation.
Declaration
public bool IsComplete { get; }
Property Value
| Type | Description |
|---|---|
| bool |
Remarks
This property reflects a snapshot of the internal state. A looping timer returns
false between cycles because ElapsedTime is reset to the
remainder after each completed cycle.
IsLooping
Gets or sets a value indicating whether the timer should automatically restart
when it completes. When true, the timer resets its elapsed time and continues
running after each cycle, incrementing LoopCount each time.
Declaration
public bool IsLooping { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
Remarks
Looping can be bounded by setting MaxLoops to a positive value. When the loop count reaches MaxLoops the timer stops automatically and fires OnStop. Use SetLooping(bool) to set this property as part of a fluent chain.
IsPaused
Gets a value indicating whether the timer is currently paused.
Declaration
public bool IsPaused { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsRunning
Gets a value indicating whether the timer is currently running. A timer is running if it has been started and not stopped, even if paused.
Declaration
public bool IsRunning { get; }
Property Value
| Type | Description |
|---|---|
| bool |
LoopCount
Gets the number of completed loop iterations. Only increments when IsLooping is true.
Declaration
public int LoopCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
MaxLoops
Gets or sets the maximum number of loop iterations before the timer stops automatically.
Set to 0 for infinite looping (the default). Must be non-negative.
Declaration
public int MaxLoops { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
Remarks
This property only has an effect when IsLooping is true.
Once LoopCount reaches this value the timer fires OnComplete
for the final cycle, then fires OnStop and transitions to a stopped state.
This value is not reset by Start() or Restart(), so a timer can be reused with the same loop limit across multiple runs.
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if value is negative. |
Progress
Gets the current progress of the timer as a normalized value in the range
[0.0, 1.0], where 0.0 is the start and 1.0 is full completion.
Returns 1.0 when Duration is zero or negative.
Declaration
public float Progress { get; }
Property Value
| Type | Description |
|---|---|
| float |
Remarks
This value is computed on-the-fly from ElapsedTime divided by
Duration and is always clamped to [0.0, 1.0]. During a looping
cycle the progress resets to near 0.0 after each OnComplete
event, reflecting the start of the new cycle.
RemainingTime
Gets the remaining time until the timer completes, in seconds. Returns 0 if the timer has completed or if duration is 0.
Declaration
public float RemainingTime { get; }
Property Value
| Type | Description |
|---|---|
| float |
TimeScale
Gets or sets the time scale multiplier applied to each incoming delta time in
Update(float). Use values less than 1.0 for slow motion and values
greater than 1.0 for fast-forward. Default is 1.0.
Declaration
public float TimeScale { get; set; }
Property Value
| Type | Description |
|---|---|
| float |
Remarks
Setting this to 0.0 freezes time progression without triggering
OnPause - it is a silent speed override rather than an explicit pause.
Negative values are permitted and cause the elapsed time to count backwards, though
it will never decrease below zero. Use SetTimeScale(float) for fluent chaining.
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown when value is |
Methods
Create(float, Action)
Creates a new Timer instance with the specified duration and an optional completion callback. The timer is not started automatically; call Start() on the returned instance to begin counting.
Declaration
public static Timer Create(float duration, Action onComplete = null)
Parameters
| Type | Name | Description |
|---|---|---|
| float | duration | The duration of the timer in seconds. Must be non-negative. |
| Action | onComplete | Optional delegate to subscribe to OnComplete. May be |
Returns
| Type | Description |
|---|---|
| Timer | A new, unstarted Timer instance. |
Remarks
This factory is the recommended entry point for one-shot timers. For looping timers use CreateLooping(float, Action) instead. Example:
var timer = Timer.Create(3f, () => Debug.Log("Done")).Start();
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if |
CreateLooping(float, Action)
Creates a new looping Timer instance with the specified cycle duration and an optional per-cycle completion callback. The timer is not started automatically; call Start() on the returned instance to begin counting.
Declaration
public static Timer CreateLooping(float duration, Action onComplete = null)
Parameters
| Type | Name | Description |
|---|---|---|
| float | duration | The duration of each individual cycle in seconds. Must be non-negative. |
| Action | onComplete | Optional delegate subscribed to OnComplete, invoked at the end of every
completed cycle. May be |
Returns
| Type | Description |
|---|---|
| Timer | A new, unstarted looping Timer instance. |
Remarks
The returned timer has IsLooping set to true and loops
indefinitely unless MaxLoops is set to a positive value. Example:
var ticker = Timer.CreateLooping(1f, OnTick).SetMaxLoops(10).Start();
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if |
Pause()
Pauses the timer, preserving the current elapsed time. Has no effect if the timer is not running.
Declaration
public Timer Pause()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Reset()
Resets the timer to its initial state. The timer will be stopped and elapsed time set to zero.
Declaration
public Timer Reset()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Restart()
Declaration
public Timer Restart()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Resume()
Resumes a paused timer from where it left off. Has no effect if the timer is not paused.
Declaration
public Timer Resume()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
SetDuration(float)
Sets the duration of the timer.
Declaration
public Timer SetDuration(float duration)
Parameters
| Type | Name | Description |
|---|---|---|
| float | duration | The duration in seconds. |
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if duration is negative. |
SetElapsedTime(float)
Seeks the timer to a specific elapsed-time position without firing any events. Useful for synchronizing multiple timers or jumping to a known point in a sequence.
Declaration
public Timer SetElapsedTime(float time)
Parameters
| Type | Name | Description |
|---|---|---|
| float | time | The target elapsed time in seconds. Negative values are clamped to |
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Remarks
This method only writes to ElapsedTime directly. It does not invoke OnProgress, OnComplete, or any other event. Completion handling occurs naturally on the subsequent Update(float) call.
SetLooping(bool)
Sets whether the timer should loop.
Declaration
public Timer SetLooping(bool isLooping)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | isLooping | True to enable looping, false to disable. |
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
SetMaxLoops(int)
Sets the maximum number of loops before the timer stops.
Declaration
public Timer SetMaxLoops(int maxLoops)
Parameters
| Type | Name | Description |
|---|---|---|
| int | maxLoops | The maximum loop count. 0 for infinite looping. |
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown if maxLoops is negative. |
SetTimeScale(float)
Sets the time scale multiplier.
Declaration
public Timer SetTimeScale(float scale)
Parameters
| Type | Name | Description |
|---|---|---|
| float | scale | The time scale multiplier. |
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Start()
Starts the timer from the beginning, resetting both ElapsedTime and LoopCount to zero. If the timer was previously paused or stopped, all prior progress is discarded and a clean run begins.
Declaration
public Timer Start()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Remarks
Fires OnStart after the internal state is reset. To continue from where a paused timer left off, use Resume() instead.
Stop()
Stops the timer completely, preserving the current ElapsedTime. Has no effect if the timer is not currently running.
Declaration
public Timer Stop()
Returns
| Type | Description |
|---|---|
| Timer | This timer instance for method chaining. |
Remarks
Unlike Pause(), a stopped timer cannot be resumed - calling
Resume() after Stop has no effect. To restart from the
beginning, call Start() or Restart().
Fires OnStop if the timer was running. The elapsed time is intentionally preserved so callers can inspect how far the timer had progressed. Call Reset() first if a clean state is required.
Update(float)
Advances the timer by the specified delta time and fires any pending events. Call this once per frame (or per fixed step) to drive the timer forward.
Declaration
public void Update(float deltaTime)
Parameters
| Type | Name | Description |
|---|---|---|
| float | deltaTime | The unscaled time elapsed since the last update call, in seconds. The timer
internally multiplies this by TimeScale before accumulating it.
Typically |
Remarks
The method returns immediately if the timer is not running or is paused.
A zero-duration timer completes on the first call regardless of
deltaTime: it fires OnComplete then
OnStop and stops running.
When IsLooping is true, cycle completion uses integer
division and modulo arithmetic on the accumulated elapsed time. This avoids
floating-point drift that would accumulate from repeated subtraction. The event
firing order each cycle is: OnProgress, then OnComplete
(repeated for each completed cycle if the delta was large), then OnStop
only when the final loop limit is reached.
Events
OnComplete
Invoked when the timer completes its duration. If IsLooping is true, this event is invoked on each cycle completion.
Declaration
public event Action OnComplete
Event Type
| Type | Description |
|---|---|
| Action |
OnPause
Invoked when the timer is paused via Pause().
Declaration
public event Action OnPause
Event Type
| Type | Description |
|---|---|
| Action |
OnProgress
Invoked each update with the current progress value (0.0 to 1.0).
Declaration
public event Action<float> OnProgress
Event Type
| Type | Description |
|---|---|
| Action<float> |
OnResume
Invoked when the timer is resumed via Resume().
Declaration
public event Action OnResume
Event Type
| Type | Description |
|---|---|
| Action |
OnStart
Declaration
public event Action OnStart
Event Type
| Type | Description |
|---|---|
| Action |
OnStop
Invoked when the timer is stopped via Stop() or when it completes.
Declaration
public event Action OnStop
Event Type
| Type | Description |
|---|---|
| Action |