A game about forced loneliness, made by TACStudios
1#if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE 2#define USE_INPUT_SYSTEM 3using UnityEngine.InputSystem; 4using UnityEngine.InputSystem.UI; 5using UnityEngine.InputSystem.EnhancedTouch; 6#endif 7using System; 8using System.Collections; 9using System.Diagnostics; 10using UnityEngine.EventSystems; 11 12namespace UnityEngine.Rendering 13{ 14 [CoreRPHelpURL("Rendering-Debugger")] 15 class DebugUpdater : MonoBehaviour 16 { 17 static DebugUpdater s_Instance = null; 18 19 ScreenOrientation m_Orientation; 20 bool m_RuntimeUiWasVisibleLastFrame = false; 21 22 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] 23 static void RuntimeInit() 24 { 25#if DEVELOPMENT_BUILD || UNITY_EDITOR 26 if (DebugManager.instance.enableRuntimeUI) 27 EnableRuntime(); 28#endif 29 } 30 31 internal static void SetEnabled(bool enabled) 32 { 33 if (enabled) 34 EnableRuntime(); 35 else 36 DisableRuntime(); 37 } 38 39 static void EnableRuntime() 40 { 41 if (s_Instance != null) 42 return; 43 44 var go = new GameObject { name = "[Debug Updater]" }; 45 s_Instance = go.AddComponent<DebugUpdater>(); 46 s_Instance.m_Orientation = Screen.orientation; 47 48 DontDestroyOnLoad(go); 49 50 DebugManager.instance.EnableInputActions(); 51 52#if USE_INPUT_SYSTEM 53 EnhancedTouchSupport.Enable(); 54#endif 55 } 56 57 static void DisableRuntime() 58 { 59 DebugManager debugManager = DebugManager.instance; 60 debugManager.displayRuntimeUI = false; 61 debugManager.displayPersistentRuntimeUI = false; 62 63 if (s_Instance != null) 64 { 65 CoreUtils.Destroy(s_Instance.gameObject); 66 s_Instance = null; 67 } 68 } 69 70 internal static void HandleInternalEventSystemComponents(bool uiEnabled) 71 { 72 if (s_Instance == null) 73 return; 74 75 if (uiEnabled) 76 s_Instance.EnsureExactlyOneEventSystem(); 77 else 78 s_Instance.DestroyDebugEventSystem(); 79 } 80 81 void EnsureExactlyOneEventSystem() 82 { 83 var eventSystems = FindObjectsByType<EventSystem>(FindObjectsSortMode.None); 84 var debugEventSystem = GetComponent<EventSystem>(); 85 86 if (eventSystems.Length > 1 && debugEventSystem != null) 87 { 88 Debug.Log($"More than one EventSystem detected in scene. Destroying EventSystem owned by DebugUpdater."); 89 DestroyDebugEventSystem(); 90 } 91 else if (eventSystems.Length == 0) 92 { 93 Debug.Log($"No EventSystem available. Creating a new EventSystem to enable Rendering Debugger runtime UI."); 94 CreateDebugEventSystem(); 95 } 96 else 97 { 98 StartCoroutine(DoAfterInputModuleUpdated(CheckInputModuleExists)); 99 } 100 } 101 102 IEnumerator DoAfterInputModuleUpdated(Action action) 103 { 104 // EventSystem.current.currentInputModule is not updated immediately when EventSystem.current changes. It happens 105 // with a delay in EventSystem.Update(), so wait a couple of frames to ensure that has happened. 106 yield return new WaitForEndOfFrame(); 107 yield return new WaitForEndOfFrame(); 108 109 action.Invoke(); 110 } 111 112 void CheckInputModuleExists() 113 { 114 if (EventSystem.current != null && EventSystem.current.currentInputModule == null) 115 { 116 Debug.LogWarning("Found a game object with EventSystem component but no corresponding BaseInputModule component - Debug UI input might not work correctly."); 117 } 118 } 119 120#if USE_INPUT_SYSTEM 121 void AssignDefaultActions() 122 { 123 if (EventSystem.current != null && EventSystem.current.currentInputModule is InputSystemUIInputModule inputSystemModule) 124 { 125 // FIXME: In order to activate default input actions in player builds (required for touch input to work), 126 // we need to call InputSystemUIInputModule.AssignDefaultActions() which was added in com.unity.inputsystem@1.1.0-pre.5. 127 // However, there is a problem in InputSystem package version ordering, where it sorts this version as an 128 // older version than it should be. Hence we cannot write a version define to conditionally compile this function call. 129 // Instead, we use reflection to see if the function is there and can be invoked. 130 // 131 // Once com.unity.inputsystem@1.1.0 is available, create an INPUTSYSTEM_1_1_0_OR_GREATER version define and use it 132 // to conditionally call AssignDefaultActions(). 133 System.Reflection.MethodInfo assignDefaultActionsMethod = inputSystemModule.GetType().GetMethod("AssignDefaultActions"); 134 if (assignDefaultActionsMethod != null) 135 { 136 assignDefaultActionsMethod.Invoke(inputSystemModule, null); 137 } 138 } 139 140 CheckInputModuleExists(); 141 } 142#endif 143 144 void CreateDebugEventSystem() 145 { 146 gameObject.AddComponent<EventSystem>(); 147#if USE_INPUT_SYSTEM 148 gameObject.AddComponent<InputSystemUIInputModule>(); 149 StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions)); 150#else 151 gameObject.AddComponent<StandaloneInputModule>(); 152#endif 153 } 154 155 void DestroyDebugEventSystem() 156 { 157 var eventSystem = GetComponent<EventSystem>(); 158#if USE_INPUT_SYSTEM 159 var inputModule = GetComponent<InputSystemUIInputModule>(); 160 if (inputModule) 161 { 162 CoreUtils.Destroy(inputModule); 163 StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions)); 164 } 165#else 166 CoreUtils.Destroy(GetComponent<StandaloneInputModule>()); 167 CoreUtils.Destroy(GetComponent<BaseInput>()); 168#endif 169 CoreUtils.Destroy(eventSystem); 170 } 171 172 void Update() 173 { 174 DebugManager debugManager = DebugManager.instance; 175 176 // Runtime UI visibility can change i.e. due to scene unload - allow component cleanup in this case. 177 if (m_RuntimeUiWasVisibleLastFrame != debugManager.displayRuntimeUI) 178 { 179 HandleInternalEventSystemComponents(debugManager.displayRuntimeUI); 180 } 181 182 debugManager.UpdateActions(); 183 184 if (debugManager.GetAction(DebugAction.EnableDebugMenu) != 0.0f || 185 debugManager.GetActionToggleDebugMenuWithTouch()) 186 { 187 debugManager.displayRuntimeUI = !debugManager.displayRuntimeUI; 188 } 189 190 if (debugManager.displayRuntimeUI) 191 { 192 if (debugManager.GetAction(DebugAction.ResetAll) != 0.0f) 193 debugManager.Reset(); 194 195 if (debugManager.GetActionReleaseScrollTarget()) 196 debugManager.SetScrollTarget(null); // Allow mouse wheel scroll without causing auto-scroll 197 } 198 199 if (m_Orientation != Screen.orientation) 200 { 201 StartCoroutine(RefreshRuntimeUINextFrame()); 202 m_Orientation = Screen.orientation; 203 } 204 205 m_RuntimeUiWasVisibleLastFrame = debugManager.displayRuntimeUI; 206 } 207 208 static IEnumerator RefreshRuntimeUINextFrame() 209 { 210 yield return null; // Defer runtime UI refresh to next frame to allow canvas to update first. 211 DebugManager.instance.ReDrawOnScreenDebug(); 212 } 213 } 214}