AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
MotionControllerInfo.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using UnityEngine;
5 #if UNITY_WSA
6 #if UNITY_2017_2_OR_NEWER
7 using UnityEngine.XR.WSA.Input;
8 #else
9 using UnityEngine.VR.WSA.Input;
10 #endif
11 #endif
12 
13 namespace HoloToolkit.Unity.InputModule
14 {
19  public class MotionControllerInfo
20  {
21  public readonly GameObject ControllerParent;
22 
23 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
24  public readonly InteractionSourceHandedness Handedness;
25 #endif
26 
27  private GameObject home;
28  private Transform homePressed;
29  private Transform homeUnpressed;
30  private GameObject menu;
31  private Transform menuPressed;
32  private Transform menuUnpressed;
33  private GameObject grasp;
34  private Transform graspPressed;
35  private Transform graspUnpressed;
36  private GameObject thumbstickPress;
37  private Transform thumbstickPressed;
38  private Transform thumbstickUnpressed;
39  private GameObject thumbstickX;
40  private Transform thumbstickXMin;
41  private Transform thumbstickXMax;
42  private GameObject thumbstickY;
43  private Transform thumbstickYMin;
44  private Transform thumbstickYMax;
45  private GameObject select;
46  private Transform selectPressed;
47  private Transform selectUnpressed;
48  private GameObject touchpadPress;
49  private Transform touchpadPressed;
50  private Transform touchpadUnpressed;
51  private GameObject touchpadTouchX;
52  private Transform touchpadTouchXMin;
53  private Transform touchpadTouchXMax;
54  private GameObject touchpadTouchY;
55  private Transform touchpadTouchYMin;
56  private Transform touchpadTouchYMax;
57  private GameObject touchpadTouchVisualizer;
58  private GameObject pointingPose;
59 
60  // These values are used to determine if a button's state has changed.
61  private bool wasGrasped;
62  private bool wasMenuPressed;
63  private bool wasHomePressed;
64  private bool wasThumbstickPressed;
65  private bool wasTouchpadPressed;
66  private bool wasTouchpadTouched;
67  private Vector2 lastThumbstickPosition;
68  private Vector2 lastTouchpadPosition;
69  private double lastSelectPressedAmount;
70 
71  public MotionControllerInfo(GameObject controllerParent
72 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
73  , InteractionSourceHandedness handedness
74 #endif
75  )
76  {
77  ControllerParent = controllerParent;
78 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
79  Handedness = handedness;
80 #endif
81  }
82 
84  {
85  // Controller button elements
86  Home,
87  Menu,
88  Grasp,
89  Thumbstick,
90  Select,
91  Touchpad,
92  // Controller body elements & poses
93  PointingPose
94  }
95 
96  public bool TryGetElement(ControllerElementEnum element, out Transform elementTransform)
97  {
98  switch (element)
99  {
100  // control elements
101  case ControllerElementEnum.Home:
102  if (home != null)
103  {
104  elementTransform = home.transform;
105  return true;
106  }
107  break;
108  case ControllerElementEnum.Menu:
109  if (menu != null)
110  {
111  elementTransform = menu.transform;
112  return true;
113  }
114  break;
115  case ControllerElementEnum.Select:
116  if (select != null)
117  {
118  elementTransform = select.transform;
119  return true;
120  }
121  break;
122  case ControllerElementEnum.Grasp:
123  if (grasp != null)
124  {
125  elementTransform = grasp.transform;
126  return true;
127  }
128  break;
129  case ControllerElementEnum.Thumbstick:
130  if (thumbstickPress != null)
131  {
132  elementTransform = thumbstickPress.transform;
133  return true;
134  }
135  break;
136  case ControllerElementEnum.Touchpad:
137  if (touchpadPress != null)
138  {
139  elementTransform = touchpadPress.transform;
140  return true;
141  }
142  break;
143  // body elements & poses
144  case ControllerElementEnum.PointingPose:
145  if (pointingPose != null)
146  {
147  elementTransform = pointingPose.transform;
148  return true;
149  }
150  break;
151  }
152 
153  elementTransform = null;
154  return false;
155  }
156 
164  public void LoadInfo(Transform[] childTransforms)
165  {
166  foreach (Transform child in childTransforms)
167  {
168  // Animation bounds are named in two pairs:
169  // pressed/unpressed and min/max. There is also a value
170  // transform, which is the transform to modify to
171  // animate the interactions. We also look for the
172  // touch transform, in order to spawn the touchpadTouched
173  // visualizer.
174  switch (child.name.ToLower())
175  {
176  case "touch":
177  touchpadTouchVisualizer = MotionControllerVisualizer.Instance.SpawnTouchpadVisualizer(child);
178  break;
179  case "pointing_pose":
180  pointingPose = child.gameObject;
181  break;
182  case "pressed":
183  switch (child.parent.name.ToLower())
184  {
185  case "home":
186  homePressed = child;
187  break;
188  case "menu":
189  menuPressed = child;
190  break;
191  case "grasp":
192  graspPressed = child;
193  break;
194  case "select":
195  selectPressed = child;
196  break;
197  case "thumbstick_press":
198  thumbstickPressed = child;
199  break;
200  case "touchpad_press":
201  touchpadPressed = child;
202  break;
203  }
204  break;
205  case "unpressed":
206  switch (child.parent.name.ToLower())
207  {
208  case "home":
209  homeUnpressed = child;
210  break;
211  case "menu":
212  menuUnpressed = child;
213  break;
214  case "grasp":
215  graspUnpressed = child;
216  break;
217  case "select":
218  selectUnpressed = child;
219  break;
220  case "thumbstick_press":
221  thumbstickUnpressed = child;
222  break;
223  case "touchpad_press":
224  touchpadUnpressed = child;
225  break;
226  }
227  break;
228  case "min":
229  switch (child.parent.name.ToLower())
230  {
231  case "thumbstick_x":
232  thumbstickXMin = child;
233  break;
234  case "thumbstick_y":
235  thumbstickYMin = child;
236  break;
237  case "touchpad_touch_x":
238  touchpadTouchXMin = child;
239  break;
240  case "touchpad_touch_y":
241  touchpadTouchYMin = child;
242  break;
243  }
244  break;
245  case "max":
246  switch (child.parent.name.ToLower())
247  {
248  case "thumbstick_x":
249  thumbstickXMax = child;
250  break;
251  case "thumbstick_y":
252  thumbstickYMax = child;
253  break;
254  case "touchpad_touch_x":
255  touchpadTouchXMax = child;
256  break;
257  case "touchpad_touch_y":
258  touchpadTouchYMax = child;
259  break;
260  }
261  break;
262  case "value":
263  switch (child.parent.name.ToLower())
264  {
265  case "home":
266  home = child.gameObject;
267  break;
268  case "menu":
269  menu = child.gameObject;
270  break;
271  case "grasp":
272  grasp = child.gameObject;
273  break;
274  case "select":
275  select = child.gameObject;
276  break;
277  case "thumbstick_press":
278  thumbstickPress = child.gameObject;
279  break;
280  case "thumbstick_x":
281  thumbstickX = child.gameObject;
282  break;
283  case "thumbstick_y":
284  thumbstickY = child.gameObject;
285  break;
286  case "touchpad_press":
287  touchpadPress = child.gameObject;
288  break;
289  case "touchpad_touch_x":
290  touchpadTouchX = child.gameObject;
291  break;
292  case "touchpad_touch_y":
293  touchpadTouchY = child.gameObject;
294  break;
295  }
296  break;
297  }
298  }
299  }
300 
301  public void AnimateGrasp(bool isGrasped)
302  {
303  if (grasp != null && graspPressed != null && graspUnpressed != null && isGrasped != wasGrasped)
304  {
305  SetLocalPositionAndRotation(grasp, isGrasped ? graspPressed : graspUnpressed);
306  wasGrasped = isGrasped;
307  }
308  }
309 
310  public void AnimateMenu(bool isMenuPressed)
311  {
312  if (menu != null && menuPressed != null && menuUnpressed != null && isMenuPressed != wasMenuPressed)
313  {
314  SetLocalPositionAndRotation(menu, isMenuPressed ? menuPressed : menuUnpressed);
315  wasMenuPressed = isMenuPressed;
316  }
317  }
318 
319  public void AnimateHome(bool isHomePressed)
320  {
321  if (home != null && homePressed != null && homeUnpressed != null && isHomePressed != wasHomePressed)
322  {
323  SetLocalPositionAndRotation(home, isHomePressed ? homePressed : homeUnpressed);
324  wasHomePressed = isHomePressed;
325  }
326  }
327 
328  public void AnimateSelect(float newSelectPressedAmount)
329  {
330  if (select != null && selectPressed != null && selectUnpressed != null && newSelectPressedAmount != lastSelectPressedAmount)
331  {
332  select.transform.localPosition = Vector3.Lerp(selectUnpressed.localPosition, selectPressed.localPosition, newSelectPressedAmount);
333  select.transform.localRotation = Quaternion.Lerp(selectUnpressed.localRotation, selectPressed.localRotation, newSelectPressedAmount);
334  lastSelectPressedAmount = newSelectPressedAmount;
335  }
336  }
337 
338  public void AnimateThumbstick(bool isThumbstickPressed, Vector2 newThumbstickPosition)
339  {
340  if (thumbstickPress != null && thumbstickPressed != null && thumbstickUnpressed != null && isThumbstickPressed != wasThumbstickPressed)
341  {
342  SetLocalPositionAndRotation(thumbstickPress, isThumbstickPressed ? thumbstickPressed : thumbstickUnpressed);
343  wasThumbstickPressed = isThumbstickPressed;
344  }
345 
346  if (thumbstickX != null && thumbstickY != null && thumbstickXMin != null && thumbstickXMax != null && thumbstickYMin != null && thumbstickYMax != null && newThumbstickPosition != lastThumbstickPosition)
347  {
348  Vector2 thumbstickNormalized = (newThumbstickPosition + Vector2.one) * 0.5f;
349 
350  thumbstickX.transform.localPosition = Vector3.Lerp(thumbstickXMin.localPosition, thumbstickXMax.localPosition, thumbstickNormalized.x);
351  thumbstickX.transform.localRotation = Quaternion.Lerp(thumbstickXMin.localRotation, thumbstickXMax.localRotation, thumbstickNormalized.x);
352 
353  thumbstickY.transform.localPosition = Vector3.Lerp(thumbstickYMax.localPosition, thumbstickYMin.localPosition, thumbstickNormalized.y);
354  thumbstickY.transform.localRotation = Quaternion.Lerp(thumbstickYMax.localRotation, thumbstickYMin.localRotation, thumbstickNormalized.y);
355 
356  lastThumbstickPosition = newThumbstickPosition;
357  }
358  }
359 
360  public void AnimateTouchpad(bool isTouchpadPressed, bool isTouchpadTouched, Vector2 newTouchpadPosition)
361  {
362  if (touchpadPress != null && touchpadPressed != null && touchpadUnpressed != null && isTouchpadPressed != wasTouchpadPressed)
363  {
364  SetLocalPositionAndRotation(touchpadPress, isTouchpadPressed ? touchpadPressed : touchpadUnpressed);
365  wasTouchpadPressed = isTouchpadPressed;
366  }
367 
368  if (touchpadTouchVisualizer != null && isTouchpadTouched != wasTouchpadTouched)
369  {
370  touchpadTouchVisualizer.SetActive(isTouchpadTouched);
371  wasTouchpadTouched = isTouchpadTouched;
372  }
373 
374  if (touchpadTouchX != null && touchpadTouchY != null && touchpadTouchXMin != null && touchpadTouchXMax != null && touchpadTouchYMin != null && touchpadTouchYMax != null && newTouchpadPosition != lastTouchpadPosition)
375  {
376  Vector2 touchpadNormalized = (newTouchpadPosition + Vector2.one) * 0.5f;
377 
378  touchpadTouchX.transform.localPosition = Vector3.Lerp(touchpadTouchXMin.localPosition, touchpadTouchXMax.localPosition, touchpadNormalized.x);
379  touchpadTouchX.transform.localRotation = Quaternion.Lerp(touchpadTouchXMin.localRotation, touchpadTouchXMax.localRotation, touchpadNormalized.x);
380 
381  touchpadTouchY.transform.localPosition = Vector3.Lerp(touchpadTouchYMax.localPosition, touchpadTouchYMin.localPosition, touchpadNormalized.y);
382  touchpadTouchY.transform.localRotation = Quaternion.Lerp(touchpadTouchYMax.localRotation, touchpadTouchYMin.localRotation, touchpadNormalized.y);
383 
384  lastTouchpadPosition = newTouchpadPosition;
385  }
386  }
387 
388  private void SetLocalPositionAndRotation(GameObject buttonGameObject, Transform newTransform)
389  {
390  buttonGameObject.transform.localPosition = newTransform.localPosition;
391  buttonGameObject.transform.localRotation = newTransform.localRotation;
392  }
393 
394  public void SetRenderersVisible(bool visible)
395  {
396  MeshRenderer[] renderers = ControllerParent.GetComponentsInChildren<MeshRenderer>();
397  for (int i = 0; i < renderers.Length; i++)
398  {
399  renderers[i].enabled = visible;
400  }
401  }
402  }
403 }
void AnimateThumbstick(bool isThumbstickPressed, Vector2 newThumbstickPosition)
This script spawns a specific GameObject when a controller is detected and animates the controller po...
This script keeps track of the GameObjects for each button on the controller. It also keeps track of ...
IsHandVisible AND IsInputSourceDown
void LoadInfo(Transform[] childTransforms)
Iterates through the Transform array to find specifically named GameObjects. These GameObjects specif...
void AnimateTouchpad(bool isTouchpadPressed, bool isTouchpadTouched, Vector2 newTouchpadPosition)
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
bool TryGetElement(ControllerElementEnum element, out Transform elementTransform)