Skip to content

Commit 6bea4e8

Browse files
author
Rene Damm
authored
NEW: 'UI vs Game Input' sample (#1377).
1 parent ff5a10d commit 6bea4e8

31 files changed

+4957
-35
lines changed

Assets/Samples/UIvsGameInput.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"displayName": "UI vs. Game Input",
3+
"description": "An example that shows how to deal with ambiguities that may arrise when overlaying interactive UI elements on top of a game scene."
4+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
%YAML 1.1
2+
%TAG !u! tag:unity3d.com,2011:
3+
--- !u!1001 &100100000
4+
Prefab:
5+
m_ObjectHideFlags: 1
6+
serializedVersion: 2
7+
m_Modification:
8+
m_TransformParent: {fileID: 0}
9+
m_Modifications: []
10+
m_RemovedComponents: []
11+
m_SourcePrefab: {fileID: 0}
12+
m_RootGameObject: {fileID: 1050929111787496}
13+
m_IsPrefabAsset: 1
14+
--- !u!1 &1050929111787496
15+
GameObject:
16+
m_ObjectHideFlags: 0
17+
m_CorrespondingSourceObject: {fileID: 0}
18+
m_PrefabInternal: {fileID: 100100000}
19+
serializedVersion: 6
20+
m_Component:
21+
- component: {fileID: 4939001955002736}
22+
- component: {fileID: 33329194892259988}
23+
- component: {fileID: 65754914235384544}
24+
- component: {fileID: 23498649278503262}
25+
- component: {fileID: 54430940299048930}
26+
m_Layer: 0
27+
m_Name: SimpleProjectile
28+
m_TagString: Untagged
29+
m_Icon: {fileID: 0}
30+
m_NavMeshLayer: 0
31+
m_StaticEditorFlags: 0
32+
m_IsActive: 1
33+
--- !u!4 &4939001955002736
34+
Transform:
35+
m_ObjectHideFlags: 1
36+
m_CorrespondingSourceObject: {fileID: 0}
37+
m_PrefabInternal: {fileID: 100100000}
38+
m_GameObject: {fileID: 1050929111787496}
39+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
40+
m_LocalPosition: {x: 0, y: 0, z: 0}
41+
m_LocalScale: {x: 0.2921129, y: 0.2921129, z: 0.2921129}
42+
m_Children: []
43+
m_Father: {fileID: 0}
44+
m_RootOrder: 0
45+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
46+
--- !u!23 &23498649278503262
47+
MeshRenderer:
48+
m_ObjectHideFlags: 1
49+
m_CorrespondingSourceObject: {fileID: 0}
50+
m_PrefabInternal: {fileID: 100100000}
51+
m_GameObject: {fileID: 1050929111787496}
52+
m_Enabled: 1
53+
m_CastShadows: 1
54+
m_ReceiveShadows: 1
55+
m_DynamicOccludee: 1
56+
m_MotionVectors: 1
57+
m_LightProbeUsage: 1
58+
m_ReflectionProbeUsage: 1
59+
m_RenderingLayerMask: 4294967295
60+
m_Materials:
61+
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
62+
m_StaticBatchInfo:
63+
firstSubMesh: 0
64+
subMeshCount: 0
65+
m_StaticBatchRoot: {fileID: 0}
66+
m_ProbeAnchor: {fileID: 0}
67+
m_LightProbeVolumeOverride: {fileID: 0}
68+
m_ScaleInLightmap: 1
69+
m_PreserveUVs: 1
70+
m_IgnoreNormalsForChartDetection: 0
71+
m_ImportantGI: 0
72+
m_StitchLightmapSeams: 0
73+
m_SelectedEditorRenderState: 3
74+
m_MinimumChartSize: 4
75+
m_AutoUVMaxDistance: 0.5
76+
m_AutoUVMaxAngle: 89
77+
m_LightmapParameters: {fileID: 0}
78+
m_SortingLayerID: 0
79+
m_SortingLayer: 0
80+
m_SortingOrder: 0
81+
--- !u!33 &33329194892259988
82+
MeshFilter:
83+
m_ObjectHideFlags: 1
84+
m_CorrespondingSourceObject: {fileID: 0}
85+
m_PrefabInternal: {fileID: 100100000}
86+
m_GameObject: {fileID: 1050929111787496}
87+
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
88+
--- !u!54 &54430940299048930
89+
Rigidbody:
90+
m_ObjectHideFlags: 1
91+
m_CorrespondingSourceObject: {fileID: 0}
92+
m_PrefabInternal: {fileID: 100100000}
93+
m_GameObject: {fileID: 1050929111787496}
94+
serializedVersion: 2
95+
m_Mass: 1
96+
m_Drag: 0
97+
m_AngularDrag: 0.05
98+
m_UseGravity: 1
99+
m_IsKinematic: 0
100+
m_Interpolate: 0
101+
m_Constraints: 0
102+
m_CollisionDetection: 0
103+
--- !u!65 &65754914235384544
104+
BoxCollider:
105+
m_ObjectHideFlags: 1
106+
m_CorrespondingSourceObject: {fileID: 0}
107+
m_PrefabInternal: {fileID: 100100000}
108+
m_GameObject: {fileID: 1050929111787496}
109+
m_Material: {fileID: 0}
110+
m_IsTrigger: 0
111+
m_Enabled: 1
112+
serializedVersion: 2
113+
m_Size: {x: 1, y: 1, z: 1}
114+
m_Center: {x: 0, y: 0, z: 0}

Assets/Samples/UIvsGameInput/Projectile.prefab.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# UI vs Game Input
2+
3+
>NOTE: More information related to ambiguities between UI and game input may be found [here in the documentation](http://docs.unity3d.com/Packages/[email protected]/manual/UISupport.html#ui-and-game-input).
4+
5+
When interactive UI elements are overlaid over a game view, ambiguity may arise for inputs.
6+
7+
If, for example, there is a `UI.Button` on screen that can be clicked/tapped, while clicking/tapping on the scene itself also has associated functionality, clicking on the UI button should not also trigger the corresponding action on the scene.
8+
9+
This sample demonstrates how to handle input in such a situation.
10+
11+
## The Sample Scene
12+
13+
![Scene Screenshot](./UIvsGameInput.png)
14+
15+
The sample scene has a UI button in each of the corners of the screen. The camera in the scene can be rotated and projectiles can be fired while at the same time the buttons in the UI can be clicked.
16+
17+
There are two ways to control the game:
18+
19+
1. "Pointer", i.e. mouse (optionally combined with keyboard) or touch input, and
20+
2. "Navigation", i.e. gamepad input.
21+
22+
### Mouse/Touch/Keyboard Input
23+
24+
- When clicking any of the buttons, the "status bar" text along the bottom edge of the screen changes.
25+
- Left-click-dragging with the mouse or finger-dragging with touch rotates the camera (note: only when starting the drag on the background). Alternatively, when using mouse&keyboard, holding the the left control key will engage camera control.
26+
- Right-clicking with the mouse or tapping the second finger while rotating the camera shoots a projectile.
27+
- Double-clicking/tapping on the scene resets the camera orientation.
28+
- Pressing `Escape` will bring up the game menu. With touch input, an extra button is shown in the game UI to do that.
29+
30+
### Gamepad Input
31+
32+
- The right stick rotates the camera and the right trigger fires a projectile.
33+
- Double-pressing the A button will reset the camera to its initial orientation.
34+
- Holding the left trigger switch to UI focus. UI selection is now active and can be changed with the d-pad or the sticks. The A button performs a button press.
35+
- Pressing B while in game brings up the main menu.
36+
37+
## How It Works
38+
39+
### Pointer Input
40+
41+
For the most part, input processing is done in `Update()` such that actions are processed on a per-frame basis. Responses to actions that may conflict with UI input use [`IsPointerOverGameObject`](https://docs.unity3d.com/Packages/[email protected]/api/UnityEngine.EventSystems.EventSystem.html?q=ispointerovergameobj#UnityEngine_EventSystems_EventSystem_IsPointerOverGameObject) to determine whether the pointer is currently over UI. Since this is called from `Update()` and thus *outside* of input processing (i.e. not from within an `InputAction` callback), the method can be safely called and will return an accurate result.
42+
43+
There are two implementations of handling the `Fire` action. One uses the same approach just mentioned where the action's response is dealt with once per frame. The second one, however, immediately creates a projectile within the callback and thus operates at sub-frame accuracy. For a low-frequency input such as the `Fire` action here, this is not generally a useful thing to do but it is done here for the sake of demonstration. We cannot call [`IsPointerOverGameObject`](https://docs.unity3d.com/Packages/[email protected]/api/UnityEngine.EventSystems.EventSystem.html?q=ispointerovergameobj#UnityEngine_EventSystems_EventSystem_IsPointerOverGameObject) from the action callback and thus need to use the UI's public raycasting interface to determine "over UI?" state manually for the current pointer position.
44+
45+
### Navigation Input
46+
47+
Navigation input employs an explicit mode switch to go from gameplay to UI input. This is handled by `OnUIEngage`.

Assets/Samples/UIvsGameInput/README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)