using UnityEngine.Playables; namespace UnityEngine.Timeline { /// /// Playable that controls the active state of a GameObject. /// public class ActivationControlPlayable : PlayableBehaviour { /// /// The state of a GameObject's activeness when a PlayableGraph stops. /// public enum PostPlaybackState { /// /// Set the GameObject to active when the PlayableGraph stops. /// Active, /// /// Set the GameObject to inactive when the [[PlayableGraph]] stops. /// Inactive, /// /// Revert the GameObject to the active state it was before the [[PlayableGraph]] started. /// Revert } enum InitialState { Unset, Active, Inactive } /// /// The GameObject to control. /// public GameObject gameObject = null; /// public PostPlaybackState postPlayback = PostPlaybackState.Revert; InitialState m_InitialState; /// /// Creates a ScriptPlayable with an ActivationControlPlayable behaviour attached /// /// PlayableGraph that will own the playable /// The GameObject that triggered the graph build /// The state to leave the gameObject after the graph is stopped /// Returns a playable that controls activation of a game object public static ScriptPlayable Create(PlayableGraph graph, GameObject gameObject, ActivationControlPlayable.PostPlaybackState postPlaybackState) { if (gameObject == null) return ScriptPlayable.Null; var handle = ScriptPlayable.Create(graph); var playable = handle.GetBehaviour(); playable.gameObject = gameObject; playable.postPlayback = postPlaybackState; return handle; } /// /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. /// /// The playable this behaviour is attached to. /// The information about this frame public override void OnBehaviourPlay(Playable playable, FrameData info) { if (gameObject == null) return; gameObject.SetActive(true); } /// /// This function is called when the Playable play state is changed to PlayState.Paused. /// /// The playable this behaviour is attached to. /// The information about this frame public override void OnBehaviourPause(Playable playable, FrameData info) { // OnBehaviourPause can be called if the graph is stopped for a variety of reasons // the effectivePlayState will test if the pause is due to the clip being out of bounds if (gameObject != null && info.effectivePlayState == PlayState.Paused) { gameObject.SetActive(false); } } /// /// This function is called during the ProcessFrame phase of the PlayableGraph. /// /// The playable this behaviour is attached to. /// A FrameData structure that contains information about the current frame context. /// unused public override void ProcessFrame(Playable playable, FrameData info, object userData) { if (gameObject != null)// && !gameObject.activeSelf) gameObject.SetActive(true); } /// /// This function is called when the PlayableGraph that owns this PlayableBehaviour starts. /// /// The playable this behaviour is attached to. public override void OnGraphStart(Playable playable) { if (gameObject != null) { if (m_InitialState == InitialState.Unset) m_InitialState = gameObject.activeSelf ? InitialState.Active : InitialState.Inactive; } } /// /// This function is called when the Playable that owns the PlayableBehaviour is destroyed. /// /// The playable this behaviour is attached to. public override void OnPlayableDestroy(Playable playable) { if (gameObject == null || m_InitialState == InitialState.Unset) return; switch (postPlayback) { case PostPlaybackState.Active: gameObject.SetActive(true); break; case PostPlaybackState.Inactive: gameObject.SetActive(false); break; case PostPlaybackState.Revert: gameObject.SetActive(m_InitialState == InitialState.Active); break; } } } }