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