123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
- #define USE_INPUT_SYSTEM
- using UnityEngine.InputSystem;
- using UnityEngine.InputSystem.UI;
- using UnityEngine.InputSystem.EnhancedTouch;
- #endif
- using System;
- using System.Collections;
- using System.Diagnostics;
- using UnityEngine.EventSystems;
-
- namespace UnityEngine.Rendering
- {
- [CoreRPHelpURL("Rendering-Debugger")]
- class DebugUpdater : MonoBehaviour
- {
- static DebugUpdater s_Instance = null;
-
- ScreenOrientation m_Orientation;
- bool m_RuntimeUiWasVisibleLastFrame = false;
-
- [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
- static void RuntimeInit()
- {
- #if DEVELOPMENT_BUILD || UNITY_EDITOR
- if (DebugManager.instance.enableRuntimeUI)
- EnableRuntime();
- #endif
- }
-
- internal static void SetEnabled(bool enabled)
- {
- if (enabled)
- EnableRuntime();
- else
- DisableRuntime();
- }
-
- static void EnableRuntime()
- {
- if (s_Instance != null)
- return;
-
- var go = new GameObject { name = "[Debug Updater]" };
- s_Instance = go.AddComponent<DebugUpdater>();
- s_Instance.m_Orientation = Screen.orientation;
-
- DontDestroyOnLoad(go);
-
- DebugManager.instance.EnableInputActions();
-
- #if USE_INPUT_SYSTEM
- EnhancedTouchSupport.Enable();
- #endif
- }
-
- static void DisableRuntime()
- {
- DebugManager debugManager = DebugManager.instance;
- debugManager.displayRuntimeUI = false;
- debugManager.displayPersistentRuntimeUI = false;
-
- if (s_Instance != null)
- {
- CoreUtils.Destroy(s_Instance.gameObject);
- s_Instance = null;
- }
- }
-
- internal static void HandleInternalEventSystemComponents(bool uiEnabled)
- {
- if (s_Instance == null)
- return;
-
- if (uiEnabled)
- s_Instance.EnsureExactlyOneEventSystem();
- else
- s_Instance.DestroyDebugEventSystem();
- }
-
- void EnsureExactlyOneEventSystem()
- {
- var eventSystems = FindObjectsByType<EventSystem>(FindObjectsSortMode.None);
- var debugEventSystem = GetComponent<EventSystem>();
-
- if (eventSystems.Length > 1 && debugEventSystem != null)
- {
- Debug.Log($"More than one EventSystem detected in scene. Destroying EventSystem owned by DebugUpdater.");
- DestroyDebugEventSystem();
- }
- else if (eventSystems.Length == 0)
- {
- Debug.Log($"No EventSystem available. Creating a new EventSystem to enable Rendering Debugger runtime UI.");
- CreateDebugEventSystem();
- }
- else
- {
- StartCoroutine(DoAfterInputModuleUpdated(CheckInputModuleExists));
- }
- }
-
- IEnumerator DoAfterInputModuleUpdated(Action action)
- {
- // EventSystem.current.currentInputModule is not updated immediately when EventSystem.current changes. It happens
- // with a delay in EventSystem.Update(), so wait a couple of frames to ensure that has happened.
- yield return new WaitForEndOfFrame();
- yield return new WaitForEndOfFrame();
-
- action.Invoke();
- }
-
- void CheckInputModuleExists()
- {
- if (EventSystem.current != null && EventSystem.current.currentInputModule == null)
- {
- Debug.LogWarning("Found a game object with EventSystem component but no corresponding BaseInputModule component - Debug UI input might not work correctly.");
- }
- }
-
- #if USE_INPUT_SYSTEM
- void AssignDefaultActions()
- {
- if (EventSystem.current != null && EventSystem.current.currentInputModule is InputSystemUIInputModule inputSystemModule)
- {
- // FIXME: In order to activate default input actions in player builds (required for touch input to work),
- // we need to call InputSystemUIInputModule.AssignDefaultActions() which was added in com.unity.inputsystem@1.1.0-pre.5.
- // However, there is a problem in InputSystem package version ordering, where it sorts this version as an
- // older version than it should be. Hence we cannot write a version define to conditionally compile this function call.
- // Instead, we use reflection to see if the function is there and can be invoked.
- //
- // Once com.unity.inputsystem@1.1.0 is available, create an INPUTSYSTEM_1_1_0_OR_GREATER version define and use it
- // to conditionally call AssignDefaultActions().
- System.Reflection.MethodInfo assignDefaultActionsMethod = inputSystemModule.GetType().GetMethod("AssignDefaultActions");
- if (assignDefaultActionsMethod != null)
- {
- assignDefaultActionsMethod.Invoke(inputSystemModule, null);
- }
- }
-
- CheckInputModuleExists();
- }
- #endif
-
- void CreateDebugEventSystem()
- {
- gameObject.AddComponent<EventSystem>();
- #if USE_INPUT_SYSTEM
- gameObject.AddComponent<InputSystemUIInputModule>();
- StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions));
- #else
- gameObject.AddComponent<StandaloneInputModule>();
- #endif
- }
-
- void DestroyDebugEventSystem()
- {
- var eventSystem = GetComponent<EventSystem>();
- #if USE_INPUT_SYSTEM
- var inputModule = GetComponent<InputSystemUIInputModule>();
- if (inputModule)
- {
- CoreUtils.Destroy(inputModule);
- StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions));
- }
- #else
- CoreUtils.Destroy(GetComponent<StandaloneInputModule>());
- CoreUtils.Destroy(GetComponent<BaseInput>());
- #endif
- CoreUtils.Destroy(eventSystem);
- }
-
- void Update()
- {
- DebugManager debugManager = DebugManager.instance;
-
- // Runtime UI visibility can change i.e. due to scene unload - allow component cleanup in this case.
- if (m_RuntimeUiWasVisibleLastFrame != debugManager.displayRuntimeUI)
- {
- HandleInternalEventSystemComponents(debugManager.displayRuntimeUI);
- }
-
- debugManager.UpdateActions();
-
- if (debugManager.GetAction(DebugAction.EnableDebugMenu) != 0.0f ||
- debugManager.GetActionToggleDebugMenuWithTouch())
- {
- debugManager.displayRuntimeUI = !debugManager.displayRuntimeUI;
- }
-
- if (debugManager.displayRuntimeUI)
- {
- if (debugManager.GetAction(DebugAction.ResetAll) != 0.0f)
- debugManager.Reset();
-
- if (debugManager.GetActionReleaseScrollTarget())
- debugManager.SetScrollTarget(null); // Allow mouse wheel scroll without causing auto-scroll
- }
-
- if (m_Orientation != Screen.orientation)
- {
- StartCoroutine(RefreshRuntimeUINextFrame());
- m_Orientation = Screen.orientation;
- }
-
- m_RuntimeUiWasVisibleLastFrame = debugManager.displayRuntimeUI;
- }
-
- static IEnumerator RefreshRuntimeUINextFrame()
- {
- yield return null; // Defer runtime UI refresh to next frame to allow canvas to update first.
- DebugManager.instance.ReDrawOnScreenDebug();
- }
- }
- }
|