This is a base class providing a general API for implementing custom playback logic. The API is defined by the interface ITimeflowPlayback, implemented abstractly by TimeflowPlaybackBase and concretely by TimeflowPlayback for convenience.
Timeflow Parent
This assigns the Timeflow instance to observe playback events. If none is specified explicitly, it defaults to the current active Timeflow in the scene.
Callback Methods
The following methods may be overridden to implement custom logic:
OnPlay() : Called when playback starts or resumes
OnStop() : Called when playback stops or is paused
OnUpdate() : Called each frame playback updates - only while playing
OnRewind() : Called whenever time jumps backward
OnLoop() : Called whenever looping occurs during playback
To get the current time, use TimeflowParent.CurrentTime
Register and Unregister
It is important that each script that implements ITimeflowPlayback registers itself globally, otherwise it will not receive the above event callbacks. And each script should Unregister itself when destroyed or deactivated.
The base class OnEnable and OnDisable automatically perform Register and Unregister, so in derived classes be sure to call base.OnEnable() and base.OnDisable() when these methods are overridden.
// Copyright 2024 Axon Genesis. All rights reserved.// AxonGenesis.com// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A// PARTICULAR PURPOSE.usingUnityEngine;namespaceAxonGenesis{ /// <summary> /// A simple example showing how to use the ITimeflowPlayback interface to add /// Timeflow playback events to any script. This can also be used on /// ScriptableObject types and does not have to be a MonoBehaviour. /// --- /// IMPORTANT: For your script to work in edit mode, be sure to set ExecuteInEditMode /// </summary> [ExecuteInEditMode]publicclassTimeflowPlayback:TimeflowPlaybackBase { /// <summary> /// Registers an object to receive playback events. If a game object is specified, it will /// be used to try to find the Timeflow parent in the hierarchy above. /// </summary> /// <paramname="playback">Reference to the object that imlements ITimeflowPlayback</param> /// <paramname="obj">The game object, or may be null</param>staticpublicvoidRegister(ITimeflowPlayback playback,GameObject obj =null) {if (playback.TimeflowParent==null&& obj !=null) {playback.TimeflowParent=ObjectUtil.GetComponentInSelfOrAncestors<Timeflow>(obj); }if (playback.TimeflowParent==null) playback.TimeflowParent=Timeflow.Active;if (playback.TimeflowParent==null) return;playback.TimeflowParent.RegisterPlaybackListener(playback); } /// <summary> /// Any script which calls Register must also call Unregster (preferably OnDisable) otherwise /// null reference errors may occur if objects are destroyed while Timeflow is playing. /// </summary> /// <paramname="playback"></param>staticpublicvoidUnregister(ITimeflowPlayback playback) {if (playback ==null||playback.TimeflowParent==null) return;playback.TimeflowParent.UnregisterPlaybackListener(playback); } [Tooltip("Assign the Timeflow instance or leave unassigned to automatically work with the first active Timeflow instance in the scene.")] [SerializeField]privateTimeflow _Timeflow =null;publicoverrideTimeflow TimeflowParent {get {return _Timeflow; }set {if (_Timeflow ==null) _Timeflow =Timeflow.Active; _Timeflow = value; } }protectedoverridevoidOnEnable() { base.OnEnable(); // This object must be registered to receive event callbacksif (DebugEnabled) Debug.Log($"ITimeflowPlayback.Register:{name}");TimeflowPlayback.Register(this, gameObject); }protectedoverridevoidOnDisable() { // Always be sure to unregister objects or null reference errors may occurif (DebugEnabled) Debug.Log($"ITimeflowPlayback.Unregister:{name}");TimeflowPlayback.Unregister(this); base.OnDisable(); }publicoverridevoidOnPlay() {if (DebugEnabled) Debug.Log("OnPlay"); }publicoverridevoidOnLoop() {if (DebugEnabled) Debug.Log("OnLoop"); }publicoverridevoidOnRewind() {if (DebugEnabled) Debug.Log("OnRewind"); }publicoverridevoidOnStop() {if (DebugEnabled) Debug.Log("OnStop"); }publicoverridevoidOnUpdate() {if (DebugEnabled) Debug.Log($"OnUpdate:{TimeflowParent.CurrentTime}"); } }}