123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using System;
- using UnityEngine.Playables;
- using UnityEngine.SceneManagement;
- namespace UnityEngine.Timeline
- {
- /// <summary>
- /// Playable that controls and instantiates a Prefab.
- /// </summary>
- public class PrefabControlPlayable : PlayableBehaviour
- {
- GameObject m_Instance;
- #if UNITY_EDITOR
- private bool m_IsActiveCached;
- #endif
- /// <summary>
- /// Creates a Playable with a PrefabControlPlayable behaviour attached
- /// </summary>
- /// <param name="graph">The PlayableGraph to inject the Playable into.</param>
- /// <param name="prefabGameObject">The prefab to instantiate from</param>
- /// <param name="parentTransform">Transform to parent instance to. Can be null.</param>
- /// <returns>Returns a Playabe with PrefabControlPlayable behaviour attached.</returns>
- public static ScriptPlayable<PrefabControlPlayable> Create(PlayableGraph graph, GameObject prefabGameObject, Transform parentTransform)
- {
- if (prefabGameObject == null)
- return ScriptPlayable<PrefabControlPlayable>.Null;
- var handle = ScriptPlayable<PrefabControlPlayable>.Create(graph);
- handle.GetBehaviour().Initialize(prefabGameObject, parentTransform);
- return handle;
- }
- /// <summary>
- /// The instance of the prefab created by this behaviour
- /// </summary>
- public GameObject prefabInstance
- {
- get { return m_Instance; }
- }
- /// <summary>
- /// Initializes the behaviour with a prefab and parent transform
- /// </summary>
- /// <param name="prefabGameObject">The prefab to instantiate from</param>
- /// <param name="parentTransform">Transform to parent instance to. Can be null.</param>
- /// <returns>The created instance</returns>
- public GameObject Initialize(GameObject prefabGameObject, Transform parentTransform)
- {
- if (prefabGameObject == null)
- throw new ArgumentNullException("Prefab cannot be null");
- if (m_Instance != null)
- {
- Debug.LogWarningFormat("Prefab Control Playable ({0}) has already been initialized with a Prefab ({1}).", prefabGameObject.name, m_Instance.name);
- }
- else
- {
- #if UNITY_EDITOR
- if (!Application.isPlaying)
- {
- m_Instance = (GameObject)UnityEditor.PrefabUtility.InstantiatePrefab(prefabGameObject, parentTransform);
- UnityEditor.PrefabUtility.prefabInstanceUpdated += OnPrefabUpdated;
- }
- else
- #endif
- {
- m_Instance = Object.Instantiate(prefabGameObject, parentTransform, false);
- }
- m_Instance.name = prefabGameObject.name + " [Timeline]";
- m_Instance.SetActive(false);
- SetHideFlagsRecursive(m_Instance);
- }
- return m_Instance;
- }
- /// <summary>
- /// This function is called when the Playable that owns the PlayableBehaviour is destroyed.
- /// </summary>
- /// <param name="playable">The playable this behaviour is attached to.</param>
- public override void OnPlayableDestroy(Playable playable)
- {
- if (m_Instance)
- {
- if (Application.isPlaying)
- Object.Destroy(m_Instance);
- else
- Object.DestroyImmediate(m_Instance);
- }
- #if UNITY_EDITOR
- UnityEditor.PrefabUtility.prefabInstanceUpdated -= OnPrefabUpdated;
- #endif
- }
- /// <summary>
- /// This function is called when the Playable play state is changed to Playables.PlayState.Playing.
- /// </summary>
- /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param>
- /// <param name="info">A FrameData structure that contains information about the current frame context.</param>
- public override void OnBehaviourPlay(Playable playable, FrameData info)
- {
- if (m_Instance == null)
- return;
- m_Instance.SetActive(true);
- #if UNITY_EDITOR
- m_IsActiveCached = true;
- #endif
- }
- /// <summary>
- /// This function is called when the Playable play state is changed to PlayState.Paused.
- /// </summary>
- /// <param name="playable">The playable this behaviour is attached to.</param>
- /// <param name="info">A FrameData structure that contains information about the current frame context.</param>
- 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 (m_Instance != null && info.effectivePlayState == PlayState.Paused)
- {
- m_Instance.SetActive(false);
- #if UNITY_EDITOR
- m_IsActiveCached = false;
- #endif
- }
- }
- #if UNITY_EDITOR
- void OnPrefabUpdated(GameObject go)
- {
- if (go == m_Instance)
- {
- SetHideFlagsRecursive(go);
- go.SetActive(m_IsActiveCached);
- }
- }
- #endif
- static void SetHideFlagsRecursive(GameObject gameObject)
- {
- if (gameObject == null)
- return;
- gameObject.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor;
- if (!Application.isPlaying)
- gameObject.hideFlags |= HideFlags.HideInHierarchy;
- foreach (Transform child in gameObject.transform)
- {
- SetHideFlagsRecursive(child.gameObject);
- }
- }
- }
- }
|