This cached version may be outdated.

For the latest version, please visit the live website.

Timeline

A component that combines timing measurements from an observed LocalClock or GlobalClock and any AreaClock within which it is.

This component should be attached to any GameObject that should be affected by Chronos.

Properties

TimelineMode mode { get; set; }

Determines what type of clock the timeline observes.

ValueDescription
LocalThe timeline observes a LocalClock attached to the same GameObject.
GlobalThe timeline observes a GlobalClock referenced by globalClock.
string globalClockKey { get; set; }

The key of the GlobalClock that is observed by the timeline. This value is only used for the Global mode.

bool rewindable { get; set; }

Determines whether the timeline should support rewind.

float recordingDuration { get; }

The maximum duration in seconds during which snapshots will be recorded. Higher values offer more rewind time but require more memory.

float recordingInterval { get; }

The interval in seconds at which snapshots will be recorded. Lower values offer more rewind precision but require more memory.

float availableRewindDuration { get; }

Returns the available rewind duration in seconds. 

Clock clock { get; }

The clock observed by the timeline.

float timeScale { get; }

The time scale of the timeline, computed from all observed clocks. For more information, see Clock.timeScale.

float deltaTime { get; }

The delta time of the timeline, computed from all observed clocks. For more information, see Clock.deltaTime.

float smoothDeltaTime { get; }

A smoothed out delta time. Use this value if you need to avoid spikes and fluctuations in delta times. The amount of frames over which this value is smoothed can be adjusted via smoothingDeltas.

static int smoothingDeltas { get; set; } = 5

The fixed delta time of the timeline, computed from all observed clocks. For more information, see Clock.fixedDeltaTime.

float time { get; }

The time in seconds since the creation of this timeline, computed from all observed clocks. For more information, see Clock.time.

float unscaledTime { get; }

The unscaled time in seconds since the creation of this timeline. For more information, see Clock.unscaledTime.

TimeState state { get; }

Indicates the state of the timeline.

Value Description
Accelerated

Time is accelerated (time scale > 1).

Normal

Time is in real-time (time scale = 1).

Slowed

Time is slowed (0 < time scale < 1).

Paused

Time is paused (time scale = 0).

Reversed

Time is reversed (time scale < 0).

Methods

void SetRecording(float duration, float inverval)

Sets the recording duration and interval in seconds.

This will reset the saved snapshots.

void ResetRecording()

Resets the saved snapshots.

int EstimateMemoryUsage()

Estimate the memory usage in bytes from the storage of snapshots for the current recording duration and interval.

void ReleaseFrom(AreaClock areaClock)

Releases the timeline from the specified area clock's effects.

void ReleaseFromAll()

Releases the timeline from the effects of all the area clocks within which it is.

Coroutine WaitForSeconds(float seconds)

Suspends the coroutine execution for the given amount of seconds. This method should only be used with a yield statement in coroutines.

There is currently no built-in support for rewindable coroutines due to limitations in the way .NET enumerators work. This feature is being considered for a future release if a workaround can be found. For now, if time is going backward, WaitForSeconds will simply never finish.

void CacheComponents()

The components used by the timeline are cached for performance optimization. If you add or remove built-in Unity components on the GameObject, you need to call this method to update the timeline accordingly.

void Reset()

Attempts a full manual reset of the timeline. When using game object pooling, you should call this method after despawning or before spawning.

Occurrences

To keep this documentation organized, the timeline methods to trigger occurrences can be found in the occurrence triggers section below.

Events

void OnStartPause()

Sent to every behaviour on the GameObject when the timeline starts a pause.

void OnStopPause()

Sent to every behaviour on the GameObject when the timeline stops a pause.

void OnStartRewind()

Sent to every behaviour on the GameObject when the timeline starts a rewind.

void OnStopRewind()

Sent to every behaviour on the GameObject when the timeline stops a rewind.

void OnExhaustRewind()

Sent to every behaviour on the GameObject when the timeline exhausts its rewind capacity.

void OnStartSlowDown()

Sent to every behaviour on the GameObject when the timeline starts a slow-down.

void OnStopSlowDown()

Sent to every behaviour on the GameObject when the timeline stops a slow-down.

void OnStartFastForward()

Sent to every behaviour on the GameObject when the timeline starts a fast-forward.

void OnStopFastForward()

Sent to every behaviour on the GameObject when the timeline stops a fast-forward.

Examples

Make the GameObject rotate in a framerate-independant manner by the scale of all affected clocks:


using UnityEngine;
using Chronos;

class MyBehaviour : MonoBehaviour
{
	void Update()
	{
		Timeline time = GetComponent<Timeline>();

		transform.Rotate(time.deltaTime * Vector3.one * 20);
	}
}

Make the GameObject cyan when paused:


using UnityEngine;
using Chronos;

class MyBehaviour : MonoBehaviour
{
	Color oldColor;

	void OnStartPause()
	{
		Renderer renderer = GetComponent<Renderer>();
		oldColor = renderer.material.color;
		renderer.material.color = Color.cyan;
	}

	void OnStopPause()
	{
		Renderer renderer = GetComponent<Renderer>();
		renderer.material.color = oldColor;
	}
}

Create a timeline component procedurally if it doesn't exist:


using UnityEngine;
using Chronos;

class MyBehaviour : MonoBehaviour
{
	void Awake()
	{
		Timeline time = GetComponent<Timeline>();

		if (time == null)
		{
			time = gameObject.AddComponent<Timeline>();
			time.mode = TimelineMode.Global;
			time.globalClock = Timekeeper.instance.Clock("Monsters");
		}
	}
}

It is usually much simpler to add a timeline component directly from the editor — this is purely in case you need to create your GameObjects procedurally.

Changing the GameObject's color randomly every 5 seconds. This delay will take in consideration pauses, fast-forwards and slow-downs.


using UnityEngine;
using Chronos;

class MyBehaviour : MonoBehaviour
{
	Timeline time;

	void Awake()
	{
		time = GetComponent<Timeline>();

		StartCoroutine(ChangeColor());
	}

	IEnumerator ChangeColor()
	{
		while (true)
		{
			// Use Timeline.waitForSeconds()
			// instead of new WaitForSeconds()
			yield return time.WaitForSeconds(5);

			float r = Random.Range(0, 256);
			float g = Random.Range(0, 256);
			float b = Random.Range(0, 256);

			Renderer renderer = GetComponent<Renderer>();
			renderer.material.color = new Color(r, g, b);
		}
	}
}

The previous example is not rewindable.

Create a base behaviour that will let you access the timeline component easily:


using UnityEngine;
using Chronos;

class BaseBehaviour : MonoBehaviour
{
	public Timeline time
	{
		get
		{
			return GetComponent<Timeline>();
		}
	}
}

// ... In other scripts, simply inherit from
// BaseBehaviour instead of MonoBehaviour

class MyBehaviour : BaseBehaviour
{
	void Update()
	{
		// We can now access the timeline extremely easily!
		transform.Rotate(time.deltaTime * Vector3.one * 20);
	}
}

Using a base behaviour is a good Unity design pattern, and it is certainly not limited to Chronos! If you have any methods or properties that you use very often, feel free to add them to BaseBehaviour. They'll be accessible from any script that extends it.

Components

Timelines manipulate the built-in Unity components at runtime to adjust their speeds. This allows an effortless setup in almost all cases. However, it also means that if you edit their speeds directly, Chronos will overwrite them or behave unexpectedly. To remedy this situation, you should use the properties below instead.

For more information about the script changes needed to migrate to Chronos, see the Migration page.

Animator

float animator.speed { get; set; }

The speed that is applied to the animator before time effects. Use this property instead of Animator.speed, which will be overwritten by the timeline at runtime.

Unfortunately, if you rewind an animator then let time flow normally, all of its previous recording will be reset. This is due to how Unity's animator recording methods are built. There seems to be no alternative at the moment.

Animation

float animation.speed { get; set; }

The speed that is applied to animations before time effects. Use this property instead of AnimationState.speed, which will be overwritten by the timeline at runtime.

ParticleSystem

float particleSystem.playbackSpeed { get; set; }

The playback speed that is applied to the particle system before time effects. Use this property instead of ParticleSystem.playbackSpeed, which will be overwritten by the timeline at runtime.

At extremely low speeds or time scales (< 0.25), particle systems will appear to stutter. This is due to a bug in Unity's particle simulation method. A bug report has been submitted here: ParticleSystem.Simulate truncates first parameter to 2 decimals.

float particleSystem.time { get; set; }

The playback time of the particle system. Use this property instead of ParticleSystem.time, which will be overwritten by the timeline at runtime.

bool particleSystem.isPlaying { get; }

Indicates whether the particle system is playing. Use this property instead of ParticleSystem.isPlaying, which will be overwritten by the timeline at runtime.

bool particleSystem.isPaused { get; }

Indicates whether the particle system is paused. Use this property instead of ParticleSystem.isPaused, which will be overwritten by the timeline at runtime.

bool particleSystem.isStopped { get; }

Indicates whether the particle system is stopped. Use this property instead of ParticleSystem.isStopped, which will be overwritten by the timeline at runtime.

void particleSystem.Play(bool withChildren = true)

Plays the particle system. Use this property instead of ParticleSystem.Play, which will be overwritten by the timeline at runtime.

void particleSystem.Pause(bool withChildren = true)

Pauses the particle system. Use this property instead of ParticleSystem.Pause, which will be overwritten by the timeline at runtime.

void particleSystem.Stop(bool withChildren = true)

Determines whether the particle system is alive. Use this method instead of ParticleSystem.IsAlive, which will be overwritten by the timeline at runtime.

void particleSystem.IsAlive(bool withChildren = true)

Stops the particle system. Use this property instead of ParticleSystem.Stop, which will be overwritten by the timeline at runtime.

Rigidbody (2D / 3D)

bool rigidbody.isKinematic { get; set; }

Determines whether the rigidbody is kinematic before time effects. Use this property instead of Rigidbody.isKinematic, which will be overwritten by the physics timer at runtime.

bool rigidbody.useGravity { get; set; } // 3D only

Determines whether the rigidbody uses gravity. Use this property instead of Rigidbody.useGravity, which will be overwritten by the physics timer at runtime.

float rigidbody2D.gravityScale { get; set; } // 2D only

The gravity scale of the rigidbody. Use this property instead of Rigidbody2D.gravityScale, which will be overwritten by the physics timer at runtime.

float rigidbody.mass { get; set; }

The mass of the rigidbody before time effects. Use this property instead of Rigidbody.mass, which will be overwritten by the physics timer at runtime.

Vector3 rigidbody.velocity { get; set; } 
Vector2 rigidbody2D.velocity { get; set; }

The velocity of the rigidbody before time effects. Use this property instead of Rigidbody.velocity, which will be overwritten by the physics timer at runtime.

Vector3 rigidbody.angularVelocity { get; set; }
float rigidbody2D.angularVelocity { get; set; }

The angular velocity of the rigidbody before time effects. Use this property instead of Rigidbody.angularVelocity, which will be overwritten by the physics timer at runtime.

float rigidbody.drag { get; set; }

The drag of the rigidbody before time effects. Use this property instead of Rigidbody.drag, which will be overwritten by the physics timer at runtime.

float rigidbody.angularDrag { get; set; }

The angular drag of the rigidbody before time effects. Use this property instead of Rigidbody.angularDrag, which will be overwritten by the physics timer at runtime.

void rigidbody.AddForce(Vector3 force, ForceMode mode = ForceMode.Force)
void rigidbody2D.AddForce(Vector2 force, ForceMode2D mode = ForceMode2D.Force)

The equivalent of Rigidbody.AddForce adjusted for time effects.

void rigidbody.AddRelativeForce(Vector3 force, ForceMode mode = ForceMode.Force)
void rigidbody2D.AddRelativeForce(Vector2 force, ForceMode2D mode = ForceMode2D.Force)

The equivalent of Rigidbody.AddRelativeForce adjusted for time effects.

void rigidbody.AddForceAtPosition(Vector3 force, Vector3 position, ForceMode mode = ForceMode.Force)
void rigidbody2D.AddForceAtPosition(Vector2 force, Vector2 position, ForceMode2D mode = ForceMode2D.Force)

The equivalent of Rigidbody.AddForceAtPosition adjusted for time effects.

void rigidbody.AddExplosionForce(float explosionForce, Vector3 explosionPosition, float explosionRadius, float upwardsModifier = 0, ForceMode mode = ForceMode.Force)

The equivalent of Rigidbody.AddExplosionForce adjusted for time effects.

void rigidbody.AddTorque(Vector3 force, ForceMode mode = ForceMode.Force)
void rigidbody2D.AddTorque(Vector2 force, ForceMode2D mode = ForceMode2D.Force)

The equivalent of Rigidbody.AddTorque adjusted for time effects.

void rigidbody.AddRelativeTorque(Vector3 force, ForceMode mode = ForceMode.Force)
void rigidbody2D.AddRelativeTorque(Vector2 force, ForceMode2D mode = ForceMode2D.Force)

The equivalent of Rigidbody.AddRelativeTorque adjusted for time effects.

AudioSource

float audioSource.pitch { get; set; }

The pitch that is applied to the audio source before time effects. Use this property instead of AudioSource.pitch, which will be overwritten by the timeline at runtime.

If you have multiple audio sources on your GameObject, you can all their timeline wrappers via the audioSources property.

WindZone

float windZone.windMain { get; set; }

The wind that is applied to the wind zone before time effects. Use this property instead of WindZone.windMain, which will be overwritten by the timeline at runtime.

float windZone.windTurbulence { get; set; }

The turbulence that is applied to the wind zone before time effects. Use this property instead of WindZone.windTurbulence, which will be overwritten by the timeline at runtime.

float windZone.windPulseMagnitude { get; set; }

The pulse magnitude that is applied to the wind zone before time effects. Use this property instead of WindZone.windPulseMagnitude, which will be overwritten by the timeline at runtime.

float windZone.windPulseFrequency { get; set; }

The pulse frequency that is applied to the wind zone before time effects. Use this property instead of WindZone.windPulseFrequency, which will be overwritten by the timeline at runtime.