using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Recorder; using UnityEngine.SceneManagement; namespace UnityEditor.Recorder { /// /// This class manages Recorder references to GameObjects in the form of key-value pairs saved inside Recorder assets. /// public static class BindingManager { const string k_HostGoName = "Unity-RecorderBindings"; /// /// Retrieves the GameObject bound to a specific key. /// /// The GameObject referenced by the key. /// The reference associated with the key. public static Object Get(string id) { var rcs = FindRecorderBindings(); var rc = rcs.FirstOrDefault(r => r.HasBindingValue(id)); return rc != null ? rc.GetBindingValue(id) : null; } /// /// Creates a new key and binds it to the same GameObject referenced by the specified key. /// /// The existing key from which you want to create a duplicate. /// The new key to create. public static void Duplicate(string id, string newId) { var rcs = FindRecorderBindings(); foreach (var rc in rcs) { rc.DuplicateBinding(id, newId); } } /// /// Creates a key-value pair in the Binding manager to reference a GameObject. /// /// The reference key. /// The referenced GameObject. public static void Set(string id, Object obj) { var rbs = FindRecorderBindings(); if (obj == null) { // Remove foreach (var rb in rbs) { RemoveBinding(id, rb); } } else { var scene = GetObjectScene(obj); var rb = rbs.FirstOrDefault(r => r.gameObject.scene == scene); if (rb == null) { // Add var gameObject = UnityHelpers.CreateRecorderGameObject(k_HostGoName); rb = gameObject.AddComponent(); SceneManager.MoveGameObjectToScene(rb.gameObject, scene); } // Replace rb.SetBindingValue(id, obj); foreach (var r in rbs) { if (r == rb) continue; RemoveBinding(id, r); } } } static void RemoveBinding(string id, RecorderBindings rb) { rb.RemoveBinding(id); if (rb.IsEmpty()) Object.DestroyImmediate(rb.gameObject); } internal static RecorderBindings[] FindRecorderBindings() { return Object.FindObjectsOfType(); } static Scene GetObjectScene(Object obj) { var gameObject = obj as GameObject; if (gameObject != null) return gameObject.scene; var component = obj as Component; if (component != null) return component.gameObject.scene; return SceneManager.GetActiveScene(); } } class SceneHook { const string k_HostGoName = "Unity-RecorderSessions"; static GameObject s_SessionHooksRoot; readonly string m_SessionId; GameObject m_SessionHook; public SceneHook(string sessionId) { m_SessionId = sessionId; } static GameObject GetSessionHooksRoot(bool createIfNecessary = true) { if (s_SessionHooksRoot == null) { s_SessionHooksRoot = GameObject.Find(k_HostGoName); if (s_SessionHooksRoot == null) { if (!createIfNecessary) return null; s_SessionHooksRoot = UnityHelpers.CreateRecorderGameObject(k_HostGoName); } } return s_SessionHooksRoot; } GameObject GetSessionHook() { if (m_SessionHook != null) return m_SessionHook; var host = GetSessionHooksRoot(); if (host == null) return null; m_SessionHook = GameObject.Find(m_SessionId); if (m_SessionHook == null) { m_SessionHook = new GameObject(m_SessionId); m_SessionHook.transform.parent = host.transform; } return m_SessionHook; } public IEnumerable GetRecordingSessions() { var sessionHook = GetSessionHook(); if (sessionHook != null) { var components = sessionHook.GetComponents(); foreach (var component in components) { yield return component.session; } } } public static void PrepareSessionRoot() { var host = GetSessionHooksRoot(); if (host != null) { host.hideFlags = HideFlags.None; Object.DontDestroyOnLoad(host); } } public RecordingSession CreateRecorderSessionWithRecorderComponent(RecorderSettings settings) { var component = GetRecorderComponent(settings); var session = new RecordingSession { recorder = RecordersInventory.CreateDefaultRecorder(settings), recorderGameObject = component.gameObject, recorderComponent = component }; component.session = session; return session; } public RecordingSession CreateRecorderSession(RecorderSettings settings) { var sceneHook = GetSessionHook(); if (sceneHook == null) return null; var session = new RecordingSession { recorder = RecordersInventory.CreateDefaultRecorder(settings), recorderGameObject = sceneHook }; return session; } RecorderComponent GetRecorderComponent(RecorderSettings settings) { var sceneHook = GetSessionHook(); if (sceneHook == null) return null; var component = sceneHook.GetComponentsInChildren().FirstOrDefault(r => r.session.settings == settings); if (component == null) component = sceneHook.AddComponent(); return component; } } }