mirror of
https://github.com/RPG-Research/bcirpg.git
synced 2024-04-16 14:23:01 +00:00
159 lines
5.8 KiB
C#
159 lines
5.8 KiB
C#
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|