Skip to content

Commit 73ef38f

Browse files
Fix how EventSystem component gets added to scene by DebugUpdater (#5523)
* Reworked how EventSystem components are added to scene by DebugUpdater. * Changelog
1 parent f0467f4 commit 73ef38f

File tree

3 files changed

+121
-42
lines changed

3 files changed

+121
-42
lines changed

com.unity.render-pipelines.core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The version number for this package has increased due to a version update of a r
8484
- Fixed Lens Flare 'radialScreenAttenuationCurve invisible'
8585
- Fixed Lens Flare rotation for Curve Distribution
8686
- Fixed potentially conflicting runtime Rendering Debugger UI command by adding an option to disable runtime UI altogether (1345783).
87+
- Fixed issues caused by automatically added EventSystem component, required to support Rendering Debugger Runtime UI input. (1361901)
8788

8889
### Changed
8990
- Improved the warning messages for Volumes and their Colliders.

com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ public bool displayRuntimeUI
140140
}
141141

142142
onDisplayRuntimeUIChanged(value);
143+
DebugUpdater.HandleInternalEventSystemComponents(value);
143144
}
144145
}
145146

com.unity.render-pipelines.core/Runtime/Debugging/DebugUpdater.cs

Lines changed: 119 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,27 @@
44
using UnityEngine.InputSystem.UI;
55
using UnityEngine.InputSystem.EnhancedTouch;
66
#endif
7+
using System;
78
using System.Collections;
89
using UnityEngine.EventSystems;
910

1011
namespace UnityEngine.Rendering
1112
{
1213
class DebugUpdater : MonoBehaviour
1314
{
15+
static DebugUpdater s_Instance = null;
16+
1417
ScreenOrientation m_Orientation;
18+
bool m_RuntimeUiWasVisibleLastFrame = false;
1519

1620
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
1721
static void RuntimeInit()
1822
{
19-
if (!Debug.isDebugBuild || !DebugManager.instance.enableRuntimeUI || FindObjectOfType<DebugUpdater>() != null)
23+
if (!Debug.isDebugBuild)
2024
return;
2125

22-
EnableRuntime();
26+
if (DebugManager.instance.enableRuntimeUI)
27+
EnableRuntime();
2328
}
2429

2530
internal static void SetEnabled(bool enabled)
@@ -32,20 +37,90 @@ internal static void SetEnabled(bool enabled)
3237

3338
static void EnableRuntime()
3439
{
40+
if (s_Instance != null)
41+
return;
42+
3543
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();
3750

38-
var es = FindObjectOfType<EventSystem>();
39-
if (es == null)
40-
{
41-
go.AddComponent<EventSystem>();
4251
#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+
}
48118

119+
#if USE_INPUT_SYSTEM
120+
void AssignDefaultActions()
121+
{
122+
if (EventSystem.current != null && EventSystem.current.currentInputModule is InputSystemUIInputModule inputSystemModule)
123+
{
49124
// FIXME: In order to activate default input actions in player builds (required for touch input to work),
50125
// we need to call InputSystemUIInputModule.AssignDefaultActions() which was added in com.unity.inputsystem@1.1.0-pre.5.
51126
// However, there is a problem in InputSystem package version ordering, where it sorts this version as an
@@ -54,55 +129,55 @@ static void EnableRuntime()
54129
//
55130
// Once com.unity.inputsystem@1.1.0 is available, create an INPUTSYSTEM_1_1_0_OR_GREATER version define and use it
56131
// to conditionally call AssignDefaultActions().
57-
System.Reflection.MethodInfo assignDefaultActionsMethod = uiModule.GetType().GetMethod("AssignDefaultActions");
132+
System.Reflection.MethodInfo assignDefaultActionsMethod = inputSystemModule.GetType().GetMethod("AssignDefaultActions");
58133
if (assignDefaultActionsMethod != null)
59134
{
60-
assignDefaultActionsMethod.Invoke(uiModule, null);
135+
assignDefaultActionsMethod.Invoke(inputSystemModule, null);
61136
}
62-
63-
go.SetActive(true);
64-
#else
65-
go.AddComponent<StandaloneInputModule>();
66-
#endif
67137
}
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+
}
76141
#endif
77-
}
78142

143+
void CreateDebugEventSystem()
144+
{
145+
gameObject.AddComponent<EventSystem>();
79146
#if USE_INPUT_SYSTEM
80-
EnhancedTouchSupport.Enable();
147+
gameObject.AddComponent<InputSystemUIInputModule>();
148+
StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions));
149+
#else
150+
gameObject.AddComponent<StandaloneInputModule>();
81151
#endif
82-
debugUpdater.m_Orientation = Screen.orientation;
83-
84-
DontDestroyOnLoad(go);
85-
86-
DebugManager.instance.EnableInputActions();
87152
}
88153

89-
static void DisableRuntime()
154+
void DestroyDebugEventSystem()
90155
{
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)
97160
{
98-
CoreUtils.Destroy(debugUpdater.gameObject);
161+
CoreUtils.Destroy(inputModule);
162+
StartCoroutine(DoAfterInputModuleUpdated(AssignDefaultActions));
99163
}
164+
#else
165+
CoreUtils.Destroy(GetComponent<StandaloneInputModule>());
166+
CoreUtils.Destroy(GetComponent<BaseInput>());
167+
#endif
168+
CoreUtils.Destroy(eventSystem);
100169
}
101170

102171
void Update()
103172
{
104173
DebugManager debugManager = DebugManager.instance;
105174

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+
106181
debugManager.UpdateActions();
107182

108183
if (debugManager.GetAction(DebugAction.EnableDebugMenu) != 0.0f ||
@@ -125,6 +200,8 @@ void Update()
125200
StartCoroutine(RefreshRuntimeUINextFrame());
126201
m_Orientation = Screen.orientation;
127202
}
203+
204+
m_RuntimeUiWasVisibleLastFrame = debugManager.displayRuntimeUI;
128205
}
129206

130207
static IEnumerator RefreshRuntimeUINextFrame()

0 commit comments

Comments
 (0)