A game about forced loneliness, made by TACStudios
1#if UNITY_INPUT_SYSTEM_ENABLE_UI
2using UnityEngine.EventSystems;
3
4namespace UnityEngine.InputSystem.UI
5{
6 // A pointer is identified by a single unique integer ID. It has an associated position and the ability to press
7 // on up to three buttons. It can also scroll.
8 //
9 // There's a single ExtendedPointerEventData instance allocated for the pointer which is used to retain the pointer's
10 // event state. As part of that state is specific to button presses, each button retains a partial copy of press-specific
11 // event information.
12 //
13 // A pointer can operate in 2D (mouse, pen, touch) or 3D (tracked). For 3D, screen-space 2D positions are derived
14 // via raycasts based on world-space position and orientation.
15 internal struct PointerModel
16 {
17 public bool changedThisFrame;
18 public UIPointerType pointerType => eventData.pointerType;
19
20 public Vector2 screenPosition
21 {
22 get => m_ScreenPosition;
23 set
24 {
25 if (m_ScreenPosition != value)
26 {
27 m_ScreenPosition = value;
28 changedThisFrame = true;
29 }
30 }
31 }
32
33 public Vector3 worldPosition
34 {
35 get => m_WorldPosition;
36 set
37 {
38 if (m_WorldPosition != value)
39 {
40 m_WorldPosition = value;
41 changedThisFrame = true;
42 }
43 }
44 }
45
46 public Quaternion worldOrientation
47 {
48 get => m_WorldOrientation;
49 set
50 {
51 if (m_WorldOrientation != value)
52 {
53 m_WorldOrientation = value;
54 changedThisFrame = true;
55 }
56 }
57 }
58
59 public Vector2 scrollDelta
60 {
61 get => m_ScrollDelta;
62 set
63 {
64 if (m_ScrollDelta != value)
65 {
66 changedThisFrame = true;
67 m_ScrollDelta = value;
68 }
69 }
70 }
71
72 public float pressure
73 {
74 get => m_Pressure;
75 set
76 {
77 if (m_Pressure != value)
78 {
79 changedThisFrame = true;
80 m_Pressure = value;
81 }
82 }
83 }
84
85 public float azimuthAngle
86 {
87 get => m_AzimuthAngle;
88 set
89 {
90 if (m_AzimuthAngle != value)
91 {
92 changedThisFrame = true;
93 m_AzimuthAngle = value;
94 }
95 }
96 }
97
98 public float altitudeAngle
99 {
100 get => m_AltitudeAngle;
101 set
102 {
103 if (m_AltitudeAngle != value)
104 {
105 changedThisFrame = true;
106 m_AltitudeAngle = value;
107 }
108 }
109 }
110
111 public float twist
112 {
113 get => m_Twist;
114 set
115 {
116 if (m_Twist != value)
117 {
118 changedThisFrame = true;
119 m_Twist = value;
120 }
121 }
122 }
123
124 public Vector2 radius
125 {
126 get => m_Radius;
127 set
128 {
129 if (m_Radius != value)
130 {
131 changedThisFrame = true;
132 m_Radius = value;
133 }
134 }
135 }
136
137 public ButtonState leftButton;
138 public ButtonState rightButton;
139 public ButtonState middleButton;
140 public ExtendedPointerEventData eventData;
141
142 public PointerModel(ExtendedPointerEventData eventData)
143 {
144 this.eventData = eventData;
145
146 changedThisFrame = false;
147
148 leftButton = default; leftButton.OnEndFrame();
149 rightButton = default; rightButton.OnEndFrame();
150 middleButton = default; middleButton.OnEndFrame();
151
152 m_ScreenPosition = default;
153 m_ScrollDelta = default;
154 m_WorldOrientation = default;
155 m_WorldPosition = default;
156
157 m_Pressure = default;
158 m_AzimuthAngle = default;
159 m_AltitudeAngle = default;
160 m_Twist = default;
161 m_Radius = default;
162 }
163
164 public void OnFrameFinished()
165 {
166 changedThisFrame = false;
167 scrollDelta = default;
168 leftButton.OnEndFrame();
169 rightButton.OnEndFrame();
170 middleButton.OnEndFrame();
171 }
172
173 private Vector2 m_ScreenPosition;
174 private Vector2 m_ScrollDelta;
175 private Vector3 m_WorldPosition;
176 private Quaternion m_WorldOrientation;
177
178 private float m_Pressure;
179 private float m_AzimuthAngle;
180 private float m_AltitudeAngle;
181 private float m_Twist;
182 private Vector2 m_Radius;
183
184 public void CopyTouchOrPenStateFrom(PointerEventData eventData)
185 {
186#if UNITY_2021_1_OR_NEWER
187 pressure = eventData.pressure;
188 azimuthAngle = eventData.azimuthAngle;
189 altitudeAngle = eventData.altitudeAngle;
190 twist = eventData.twist;
191 radius = eventData.radius;
192#endif
193 }
194
195 // State related to pressing and releasing individual bodies. Retains those parts of
196 // PointerInputEvent that are specific to presses and releases.
197 public struct ButtonState
198 {
199 private bool m_IsPressed;
200 private PointerEventData.FramePressState m_FramePressState;
201 private float m_PressTime;
202
203 public bool isPressed
204 {
205 get => m_IsPressed;
206 set
207 {
208 if (m_IsPressed != value)
209 {
210 m_IsPressed = value;
211
212 if (m_FramePressState == PointerEventData.FramePressState.NotChanged && value)
213 m_FramePressState = PointerEventData.FramePressState.Pressed;
214 else if (m_FramePressState == PointerEventData.FramePressState.NotChanged && !value)
215 m_FramePressState = PointerEventData.FramePressState.Released;
216 else if (m_FramePressState == PointerEventData.FramePressState.Pressed && !value)
217 m_FramePressState = PointerEventData.FramePressState.PressedAndReleased;
218 }
219 }
220 }
221
222 /// <summary>
223 /// When we "release" a button other than through user interaction (e.g. through focus switching),
224 /// we don't want this to count as an actual release that ends up clicking. This flag will cause
225 /// generated events to have <c>eligibleForClick</c> to be false.
226 /// </summary>
227 public bool ignoreNextClick
228 {
229 get => m_IgnoreNextClick;
230 set => m_IgnoreNextClick = value;
231 }
232
233 public float pressTime
234 {
235 get => m_PressTime;
236 set => m_PressTime = value;
237 }
238
239 public bool clickedOnSameGameObject
240 {
241 get => m_ClickedOnSameGameObject;
242 set => m_ClickedOnSameGameObject = value;
243 }
244
245 public bool wasPressedThisFrame => m_FramePressState == PointerEventData.FramePressState.Pressed ||
246 m_FramePressState == PointerEventData.FramePressState.PressedAndReleased;
247 public bool wasReleasedThisFrame => m_FramePressState == PointerEventData.FramePressState.Released ||
248 m_FramePressState == PointerEventData.FramePressState.PressedAndReleased;
249
250 private RaycastResult m_PressRaycast;
251 private GameObject m_PressObject;
252 private GameObject m_RawPressObject;
253 private GameObject m_LastPressObject;
254 private GameObject m_DragObject;
255 private Vector2 m_PressPosition;
256 private float m_ClickTime; // On Time.unscaledTime timeline, NOT input event time.
257 private int m_ClickCount;
258 private bool m_Dragging;
259 private bool m_ClickedOnSameGameObject;
260 private bool m_IgnoreNextClick;
261
262 public void CopyPressStateTo(PointerEventData eventData)
263 {
264 eventData.pointerPressRaycast = m_PressRaycast;
265 eventData.pressPosition = m_PressPosition;
266 eventData.clickCount = m_ClickCount;
267 eventData.clickTime = m_ClickTime;
268 // We can't set lastPress directly. Old input module uses three different event instances, one for each
269 // button. We share one instance and just switch press states. Set pointerPress twice to get the lastPress
270 // we need.
271 //
272 // NOTE: This does *NOT* quite work as stated in the docs. pointerPress is nulled out on button release which
273 // will set lastPress as a side-effect. This means that lastPress will only be non-null while no press is
274 // going on and will *NOT* refer to the last pressed object when a new object has been pressed on.
275 eventData.pointerPress = m_LastPressObject;
276 eventData.pointerPress = m_PressObject;
277 eventData.rawPointerPress = m_RawPressObject;
278 eventData.pointerDrag = m_DragObject;
279 eventData.dragging = m_Dragging;
280
281 if (ignoreNextClick)
282 eventData.eligibleForClick = false;
283 }
284
285 public void CopyPressStateFrom(PointerEventData eventData)
286 {
287 m_PressRaycast = eventData.pointerPressRaycast;
288 m_PressObject = eventData.pointerPress;
289 m_RawPressObject = eventData.rawPointerPress;
290 m_LastPressObject = eventData.lastPress;
291 m_PressPosition = eventData.pressPosition;
292 m_ClickTime = eventData.clickTime;
293 m_ClickCount = eventData.clickCount;
294 m_DragObject = eventData.pointerDrag;
295 m_Dragging = eventData.dragging;
296 }
297
298 public void OnEndFrame()
299 {
300 m_FramePressState = PointerEventData.FramePressState.NotChanged;
301 }
302 }
303 }
304}
305#endif