Skip to content

Commit f7cc21e

Browse files
authored
FIX: Fixed exceptions being thrown by OnScreenStick and improved warnings related to missing UGUI dependencies for current implementations. (#1948)
* FIX: Fixed exceptions being thrown by OnScreenStick and improved warnings related to missing UGUI dependencies for current implementations.
1 parent 483d115 commit f7cc21e

File tree

4 files changed

+80
-14
lines changed

4 files changed

+80
-14
lines changed

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ however, it has to be formatted properly to pass verification tests.
1010

1111
## [Unreleased] - yyyy-mm-dd
1212

13+
### Change
14+
- Added warning messages to both `OnScreenStick` and `OnScreenButton` Inspector editors that would display a warning message in case on-screen control components are added to a `GameObject` not part of a valid UI hierarchy.
15+
1316
### Fixed
1417
- Avoid potential crashes from `NullReferenceException` in `FireStateChangeNotifications`.
1518
- Fixed an issue where a composite binding would not be consecutively triggered after ResetDevice() has been called from the associated action handler [ISXB-746](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-746).
@@ -19,8 +22,10 @@ however, it has to be formatted properly to pass verification tests.
1922
- Fixed error thrown when Cancelling Control Scheme creation in Input Actions Editor.
2023
- Fixed Scheme Name in Control Scheme editor menu that gets reset when editing devices [ISXB-763](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-763).
2124
- Fixed an issue where `InputActionAsset.FindAction(string, bool)` would throw `System.NullReferenceException` instead of returning `null` if searching for a non-existent action with an explicit action path and using `throwIfNotFound: false`, e.g. searching for "Map/Action" when `InputActionMap` "Map" exists but no `InputAction` named "Action" exists within that map [ISXB-895](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-895).
25+
- Fixed an issue where adding a `OnScreenButton` or `OnScreenStick` to a regular GameObject would lead to exception in editor.
26+
- Fixed an issue where adding a `OnScreenStick` to a regular GameObject and entering play-mode would lead to exceptions being generated.
2227

23-
## Added
28+
### Added
2429
- Added additional device information when logging the error due to exceeding the maximum number of events processed
2530
set by `InputSystem.settings.maxEventsBytesPerUpdate`. This additional information is available in development builds
2631
only.

Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenButton.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#if PACKAGE_DOCS_GENERATION || UNITY_INPUT_SYSTEM_ENABLE_UI
2-
using System;
32
using UnityEngine.EventSystems;
43
using UnityEngine.InputSystem.Layouts;
54

@@ -45,6 +44,29 @@ protected override string controlPathInternal
4544
get => m_ControlPath;
4645
set => m_ControlPath = value;
4746
}
47+
48+
#if UNITY_EDITOR
49+
[UnityEditor.CustomEditor(typeof(OnScreenButton))]
50+
internal class OnScreenButtonEditor : UnityEditor.Editor
51+
{
52+
private UnityEditor.SerializedProperty m_ControlPathInternal;
53+
54+
public void OnEnable()
55+
{
56+
m_ControlPathInternal = serializedObject.FindProperty(nameof(OnScreenButton.m_ControlPath));
57+
}
58+
59+
public override void OnInspectorGUI()
60+
{
61+
// Current implementation has UGUI dependencies (ISXB-915, ISXB-916)
62+
UGUIOnScreenControlEditorUtils.ShowWarningIfNotPartOfCanvasHierarchy((OnScreenButton)target);
63+
64+
UnityEditor.EditorGUILayout.PropertyField(m_ControlPathInternal);
65+
66+
serializedObject.ApplyModifiedProperties();
67+
}
68+
}
69+
#endif
4870
}
4971
}
5072
#endif

Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenControl.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,5 +299,30 @@ public void Destroy()
299299
}
300300

301301
private static InlinedArray<OnScreenDeviceInfo> s_OnScreenDevices;
302+
303+
internal string GetWarningMessage()
304+
{
305+
return $"{GetType()} needs to be attached as a child to a UI Canvas and have a RectTransform component to function properly.";
306+
}
307+
}
308+
309+
internal static class UGUIOnScreenControlUtils
310+
{
311+
public static RectTransform GetCanvasRectTransform(Transform transform)
312+
{
313+
var parentTransform = transform.parent;
314+
return parentTransform != null ? transform.parent.GetComponentInParent<RectTransform>() : null;
315+
}
316+
}
317+
318+
#if UNITY_EDITOR
319+
internal static class UGUIOnScreenControlEditorUtils
320+
{
321+
public static void ShowWarningIfNotPartOfCanvasHierarchy(OnScreenControl target)
322+
{
323+
if (UGUIOnScreenControlUtils.GetCanvasRectTransform(target.transform) == null)
324+
UnityEditor.EditorGUILayout.HelpBox(target.GetWarningMessage(), UnityEditor.MessageType.Warning);
325+
}
302326
}
327+
#endif
303328
}

Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,14 @@ private void Start()
112112
m_PointerMoveAction.Enable();
113113
}
114114

115+
// Unable to setup elements according to settings if a RectTransform is not available (ISXB-915, ISXB-916).
116+
if (!(transform is RectTransform))
117+
return;
118+
115119
m_StartPos = ((RectTransform)transform).anchoredPosition;
116120

117121
if (m_Behaviour != Behaviour.ExactPositionWithDynamicOrigin) return;
122+
118123
m_PointerDownPos = m_StartPos;
119124

120125
var dynamicOrigin = new GameObject(kDynamicOriginClickable, typeof(Image));
@@ -132,38 +137,39 @@ private void Start()
132137

133138
private void BeginInteraction(Vector2 pointerPosition, Camera uiCamera)
134139
{
135-
var canvasRect = transform.parent?.GetComponentInParent<RectTransform>();
136-
if (canvasRect == null)
140+
var canvasRectTransform = UGUIOnScreenControlUtils.GetCanvasRectTransform(transform);
141+
if (canvasRectTransform == null)
137142
{
138-
Debug.LogError("OnScreenStick needs to be attached as a child to a UI Canvas to function properly.");
143+
Debug.LogError(GetWarningMessage());
139144
return;
140145
}
141146

142147
switch (m_Behaviour)
143148
{
144149
case Behaviour.RelativePositionWithStaticOrigin:
145-
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pointerPosition, uiCamera, out m_PointerDownPos);
150+
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, pointerPosition, uiCamera, out m_PointerDownPos);
146151
break;
147152
case Behaviour.ExactPositionWithStaticOrigin:
148-
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pointerPosition, uiCamera, out m_PointerDownPos);
153+
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, pointerPosition, uiCamera, out m_PointerDownPos);
149154
MoveStick(pointerPosition, uiCamera);
150155
break;
151156
case Behaviour.ExactPositionWithDynamicOrigin:
152-
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pointerPosition, uiCamera, out var pointerDown);
157+
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, pointerPosition, uiCamera, out var pointerDown);
153158
m_PointerDownPos = ((RectTransform)transform).anchoredPosition = pointerDown;
154159
break;
155160
}
156161
}
157162

158163
private void MoveStick(Vector2 pointerPosition, Camera uiCamera)
159164
{
160-
var canvasRect = transform.parent?.GetComponentInParent<RectTransform>();
161-
if (canvasRect == null)
165+
var canvasRectTransform = UGUIOnScreenControlUtils.GetCanvasRectTransform(transform);
166+
if (canvasRectTransform == null)
162167
{
163-
Debug.LogError("OnScreenStick needs to be attached as a child to a UI Canvas to function properly.");
168+
Debug.LogError(GetWarningMessage());
164169
return;
165170
}
166-
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pointerPosition, uiCamera, out var position);
171+
172+
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, pointerPosition, uiCamera, out var position);
167173
var delta = position - m_PointerDownPos;
168174

169175
switch (m_Behaviour)
@@ -253,9 +259,14 @@ private Camera GetCameraFromCanvas()
253259

254260
private void OnDrawGizmosSelected()
255261
{
256-
Gizmos.matrix = ((RectTransform)transform.parent).localToWorldMatrix;
262+
// This will not produce meaningful results unless we have a rect transform (ISXB-915, ISXB-916).
263+
var parentRectTransform = transform.parent as RectTransform;
264+
if (parentRectTransform == null)
265+
return;
266+
267+
Gizmos.matrix = parentRectTransform.localToWorldMatrix;
257268

258-
var startPos = ((RectTransform)transform).anchoredPosition;
269+
var startPos = parentRectTransform.anchoredPosition;
259270
if (Application.isPlaying)
260271
startPos = m_StartPos;
261272

@@ -457,6 +468,9 @@ public void OnEnable()
457468

458469
public override void OnInspectorGUI()
459470
{
471+
// Current implementation has UGUI dependencies (ISXB-915, ISXB-916)
472+
UGUIOnScreenControlEditorUtils.ShowWarningIfNotPartOfCanvasHierarchy((OnScreenStick)target);
473+
460474
EditorGUILayout.PropertyField(m_MovementRange);
461475
EditorGUILayout.PropertyField(m_ControlPathInternal);
462476
EditorGUILayout.PropertyField(m_Behaviour);

0 commit comments

Comments
 (0)