SceneHook.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.Recorder;
  5. using UnityEngine.SceneManagement;
  6. namespace UnityEditor.Recorder
  7. {
  8. /// <summary>
  9. /// This class manages Recorder references to GameObjects in the form of key-value pairs saved inside Recorder assets.
  10. /// </summary>
  11. public static class BindingManager
  12. {
  13. const string k_HostGoName = "Unity-RecorderBindings";
  14. /// <summary>
  15. /// Retrieves the GameObject bound to a specific key.
  16. /// </summary>
  17. /// <param name="id">The GameObject referenced by the key.</param>
  18. /// <returns>The reference associated with the key.</returns>
  19. public static Object Get(string id)
  20. {
  21. var rcs = FindRecorderBindings();
  22. var rc = rcs.FirstOrDefault(r => r.HasBindingValue(id));
  23. return rc != null ? rc.GetBindingValue(id) : null;
  24. }
  25. /// <summary>
  26. /// Creates a new key and binds it to the same GameObject referenced by the specified key.
  27. /// </summary>
  28. /// <param name="id">The existing key from which you want to create a duplicate.</param>
  29. /// <param name="newId">The new key to create.</param>
  30. public static void Duplicate(string id, string newId)
  31. {
  32. var rcs = FindRecorderBindings();
  33. foreach (var rc in rcs)
  34. {
  35. rc.DuplicateBinding(id, newId);
  36. }
  37. }
  38. /// <summary>
  39. /// Creates a key-value pair in the Binding manager to reference a GameObject.
  40. /// </summary>
  41. /// <param name="id">The reference key.</param>
  42. /// <param name="obj">The referenced GameObject.</param>
  43. public static void Set(string id, Object obj)
  44. {
  45. var rbs = FindRecorderBindings();
  46. if (obj == null)
  47. {
  48. // Remove
  49. foreach (var rb in rbs)
  50. {
  51. RemoveBinding(id, rb);
  52. }
  53. }
  54. else
  55. {
  56. var scene = GetObjectScene(obj);
  57. var rb = rbs.FirstOrDefault(r => r.gameObject.scene == scene);
  58. if (rb == null)
  59. {
  60. // Add
  61. var gameObject = UnityHelpers.CreateRecorderGameObject(k_HostGoName);
  62. rb = gameObject.AddComponent<RecorderBindings>();
  63. SceneManager.MoveGameObjectToScene(rb.gameObject, scene);
  64. }
  65. // Replace
  66. rb.SetBindingValue(id, obj);
  67. foreach (var r in rbs)
  68. {
  69. if (r == rb)
  70. continue;
  71. RemoveBinding(id, r);
  72. }
  73. }
  74. }
  75. static void RemoveBinding(string id, RecorderBindings rb)
  76. {
  77. rb.RemoveBinding(id);
  78. if (rb.IsEmpty())
  79. Object.DestroyImmediate(rb.gameObject);
  80. }
  81. internal static RecorderBindings[] FindRecorderBindings()
  82. {
  83. return Object.FindObjectsOfType<RecorderBindings>();
  84. }
  85. static Scene GetObjectScene(Object obj)
  86. {
  87. var gameObject = obj as GameObject;
  88. if (gameObject != null)
  89. return gameObject.scene;
  90. var component = obj as Component;
  91. if (component != null)
  92. return component.gameObject.scene;
  93. return SceneManager.GetActiveScene();
  94. }
  95. }
  96. class SceneHook
  97. {
  98. const string k_HostGoName = "Unity-RecorderSessions";
  99. static GameObject s_SessionHooksRoot;
  100. readonly string m_SessionId;
  101. GameObject m_SessionHook;
  102. public SceneHook(string sessionId)
  103. {
  104. m_SessionId = sessionId;
  105. }
  106. static GameObject GetSessionHooksRoot(bool createIfNecessary = true)
  107. {
  108. if (s_SessionHooksRoot == null)
  109. {
  110. s_SessionHooksRoot = GameObject.Find(k_HostGoName);
  111. if (s_SessionHooksRoot == null)
  112. {
  113. if (!createIfNecessary)
  114. return null;
  115. s_SessionHooksRoot = UnityHelpers.CreateRecorderGameObject(k_HostGoName);
  116. }
  117. }
  118. return s_SessionHooksRoot;
  119. }
  120. GameObject GetSessionHook()
  121. {
  122. if (m_SessionHook != null)
  123. return m_SessionHook;
  124. var host = GetSessionHooksRoot();
  125. if (host == null)
  126. return null;
  127. m_SessionHook = GameObject.Find(m_SessionId);
  128. if (m_SessionHook == null)
  129. {
  130. m_SessionHook = new GameObject(m_SessionId);
  131. m_SessionHook.transform.parent = host.transform;
  132. }
  133. return m_SessionHook;
  134. }
  135. public IEnumerable<RecordingSession> GetRecordingSessions()
  136. {
  137. var sessionHook = GetSessionHook();
  138. if (sessionHook != null)
  139. {
  140. var components = sessionHook.GetComponents<RecorderComponent>();
  141. foreach (var component in components)
  142. {
  143. yield return component.session;
  144. }
  145. }
  146. }
  147. public static void PrepareSessionRoot()
  148. {
  149. var host = GetSessionHooksRoot();
  150. if (host != null)
  151. {
  152. host.hideFlags = HideFlags.None;
  153. Object.DontDestroyOnLoad(host);
  154. }
  155. }
  156. public RecordingSession CreateRecorderSessionWithRecorderComponent(RecorderSettings settings)
  157. {
  158. var component = GetRecorderComponent(settings);
  159. var session = new RecordingSession
  160. {
  161. recorder = RecordersInventory.CreateDefaultRecorder(settings),
  162. recorderGameObject = component.gameObject,
  163. recorderComponent = component
  164. };
  165. component.session = session;
  166. return session;
  167. }
  168. public RecordingSession CreateRecorderSession(RecorderSettings settings)
  169. {
  170. var sceneHook = GetSessionHook();
  171. if (sceneHook == null)
  172. return null;
  173. var session = new RecordingSession
  174. {
  175. recorder = RecordersInventory.CreateDefaultRecorder(settings),
  176. recorderGameObject = sceneHook
  177. };
  178. return session;
  179. }
  180. RecorderComponent GetRecorderComponent(RecorderSettings settings)
  181. {
  182. var sceneHook = GetSessionHook();
  183. if (sceneHook == null)
  184. return null;
  185. var component = sceneHook.GetComponentsInChildren<RecorderComponent>().FirstOrDefault(r => r.session.settings == settings);
  186. if (component == null)
  187. component = sceneHook.AddComponent<RecorderComponent>();
  188. return component;
  189. }
  190. }
  191. }