AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
CustomInputControl.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 
6 namespace HoloToolkit.Unity.InputModule
7 {
11  public class CustomInputControl : MonoBehaviour
12  {
13  public float ControllerReturnFactor = 0.25f;
14  public float ControllerTimeBeforeReturn = 0.5f;
15 
16  [Tooltip("Use unscaled time. This is useful for games that have a pause mechanism or otherwise adjust the game timescale.")]
17  public bool UseUnscaledTime = true;
18 
27 
29 
30  public Color ActiveControllerColor;
31  public Color DroppedControllerColor;
32 
37  public bool VisualizeController = true;
38  public GameObject ControllerVisualizer;
39 
40  public Texture HandUpTexture;
41  public Texture HandDownTexture;
42 
43  public bool ShowPointingRay;
44 
45  public bool ControllerInView { get; private set; }
46 
47  public Vector3 InitialPosition;
48 
49  private Vector3 localPosition;
50  private Vector3 localRotation;
51 
52  private Renderer visualRenderer;
53  private MaterialPropertyBlock visualPropertyBlock;
54  private int mainTexId;
55 
56  private float timeBeforeReturn;
57 
58  private void Awake()
59  {
60  if (!Application.isEditor)
61  {
62  Destroy(gameObject);
63  }
64 
65  mainTexId = Shader.PropertyToID("_MainTex");
66 
67  ControllerSourceState.Pressed = false;
68  ControllerSourceState.Grasped = false;
69  ControllerSourceState.MenuPressed = false;
70  ControllerSourceState.SelectPressed = false;
71  ControllerSourceState.SourcePose = new DebugInteractionSourcePose
72  {
73  IsPositionAvailable = false,
74  IsRotationAvailable = false
75  };
76 
77  localPosition = ControllerVisualizer.transform.position;
78  InitialPosition = localPosition;
79  ControllerSourceState.SourcePose.Position = localPosition;
80  ControllerSourceState.SourcePose.Rotation = ControllerVisualizer.transform.rotation;
81  // we reuse localPosition here as we have no real way to source a grip position
82  // in the Editor, other than an arbitrary offset
83  ControllerSourceState.SourcePose.GripPosition = localPosition;
84  ControllerSourceState.SourcePose.GripRotation = ControllerVisualizer.transform.rotation;
85 
86  visualRenderer = ControllerVisualizer.GetComponent<Renderer>();
87  visualPropertyBlock = new MaterialPropertyBlock();
88  visualRenderer.SetPropertyBlock(visualPropertyBlock);
89  }
90 
91  private void Update()
92  {
93  UpdateControllerVisualization();
94 
95  float deltaTime = UseUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
96 
97  float smoothingFactor = deltaTime * 30.0f * ControllerReturnFactor;
98 
99  if (timeBeforeReturn > 0.0f)
100  {
101  timeBeforeReturn = Mathf.Clamp(timeBeforeReturn - deltaTime, 0.0f, ControllerTimeBeforeReturn);
102  }
103 
104  ControllerSourceState.SelectPressed = SelectButtonControl.Pressed();
105  ControllerSourceState.Pressed = ControllerSourceState.SelectPressed;
106 
107  if (MenuButtonControl)
108  {
109  ControllerSourceState.MenuPressed = MenuButtonControl.Pressed();
110  }
111 
112  if (GraspControl)
113  {
114  ControllerSourceState.Grasped = GraspControl.Pressed();
115  }
116 
117  if (ControllerSourceState.Pressed)
118  {
119  timeBeforeReturn = ControllerTimeBeforeReturn;
120  }
121 
122  if (timeBeforeReturn <= 0.0f)
123  {
124  localPosition = Vector3.Slerp(localPosition, InitialPosition, smoothingFactor);
125  if (localPosition == InitialPosition)
126  {
127  ControllerInView = false;
128  }
129  }
130 
131  Vector3 translate = Vector3.zero;
132 
133  if (PrimaryAxisTranslateControl && SecondaryAxisTranslateControl)
134  {
135  translate = PrimaryAxisTranslateControl.GetDisplacementVector3() +
136  SecondaryAxisTranslateControl.GetDisplacementVector3();
137 
138  ControllerSourceState.SourcePose.IsPositionAvailable = true;
139  }
140 
141  if (PrimaryAxisRotateControl && SecondaryAxisRotateControl && TertiaryAxisRotateControl)
142  {
143  Vector3 rotate = PrimaryAxisRotateControl.GetDisplacementVector3() +
144  SecondaryAxisRotateControl.GetDisplacementVector3() +
145  TertiaryAxisRotateControl.GetDisplacementVector3();
146 
147  if ((PrimaryAxisRotateControl.axisType != AxisController.AxisType.None && PrimaryAxisRotateControl.ShouldControl()) ||
148  (SecondaryAxisRotateControl.axisType != AxisController.AxisType.None && SecondaryAxisRotateControl.ShouldControl()) ||
149  (TertiaryAxisRotateControl.axisType != AxisController.AxisType.None && TertiaryAxisRotateControl.ShouldControl()))
150  {
151  ControllerSourceState.SourcePose.IsRotationAvailable = true;
152  localRotation += rotate;
153  }
154  }
155 
156  // If there is a mouse translate with a modifier key and it is held down, do not reset the controller position.
157  bool controllerTranslateActive =
158  (PrimaryAxisTranslateControl.axisType == AxisController.AxisType.Mouse &&
159  PrimaryAxisTranslateControl.buttonType != ButtonController.ButtonType.None &&
160  PrimaryAxisTranslateControl.ShouldControl()) ||
161  (SecondaryAxisTranslateControl.axisType == AxisController.AxisType.Mouse &&
162  SecondaryAxisTranslateControl.buttonType != ButtonController.ButtonType.None &&
163  SecondaryAxisTranslateControl.ShouldControl());
164 
165  if (controllerTranslateActive ||
166  ControllerSourceState.SelectPressed ||
167  ControllerSourceState.MenuPressed ||
168  ControllerSourceState.Grasped ||
169  ControllerSourceState.SourcePose.IsRotationAvailable)
170  {
171  timeBeforeReturn = ControllerTimeBeforeReturn;
172  ControllerInView = true;
173  }
174 
175  localPosition += translate;
176  ControllerSourceState.SourcePose.Position = CameraCache.Main.transform.position + CameraCache.Main.transform.TransformVector(localPosition);
177  ControllerSourceState.SourcePose.GripPosition = CameraCache.Main.transform.position + CameraCache.Main.transform.TransformVector(localPosition);
178 
179  ControllerVisualizer.transform.position = ControllerSourceState.SourcePose.Position;
180  ControllerVisualizer.transform.forward = CameraCache.Main.transform.forward;
181 
182  ControllerVisualizer.transform.Rotate(localRotation);
183 
184  ControllerSourceState.SourcePose.Rotation = ControllerVisualizer.transform.rotation;
185 
186  visualPropertyBlock.SetTexture(mainTexId, ControllerSourceState.Pressed ? HandDownTexture : HandUpTexture);
187  visualRenderer.SetPropertyBlock(visualPropertyBlock);
188 
189  ControllerSourceState.SourcePose.TryGetFunctionsReturnTrue = ControllerInView;
190 
191  if (ControllerInView && ControllerSourceState.SourcePose.IsRotationAvailable && ControllerSourceState.SourcePose.IsPositionAvailable)
192  {
193  // Draw ray
194  Vector3 up = ControllerVisualizer.transform.TransformDirection(Vector3.up);
195  ControllerSourceState.SourcePose.PointerRay = new Ray(ControllerVisualizer.transform.position, up);
196 
197  Ray newRay;
198  if (ControllerSourceState.SourcePose.TryGetPointerRay(out newRay))
199  {
200  if (ShowPointingRay && Physics.Raycast(newRay))
201  {
202  // TODO shanama: get pretty ray here, maybe an "active" ray and an "inactive" ray for when buttons are pressed
203  Debug.DrawRay(newRay.origin, newRay.direction, Color.cyan);
204  }
205  }
206  }
207  else
208  {
209  ControllerSourceState.SourcePose.PointerRay = null;
210  }
211  }
212 
213  private void UpdateControllerVisualization()
214  {
215  visualRenderer.material.SetColor("_Color", ControllerInView ? ActiveControllerColor : DroppedControllerColor);
216 
217  if (ControllerVisualizer.activeSelf != VisualizeController)
218  {
219  ControllerVisualizer.SetActive(VisualizeController);
220  }
221  }
222  }
223 }
ButtonController provides a per key or button component for the Manual input Controls in the Unity Ed...
bool Pressed()
Returns true if the configured button is currently pressed.
bool ShouldControl()
Only allow the mouse to control rotation when Unity has focus. This enables the player to temporarily...
AxisType
Type of input axis, based on device.
ButtonController.ButtonType buttonType
bool TryGetFunctionsReturnTrue
In the typical InteractionSourcePose, the hardware determines if TryGetPosition and TryGetVelocity wi...
Vector3 GetDisplacementVector3()
Get a Vector3 populated with axis mapped displacements.
ButtonType
These enums allow us to activate an axis only by a key press, such as CTRL mouse or ALT mouse ...
The purpose of this class is to provide a cached reference to the main camera. Calling Camera...
Definition: CameraCache.cs:12
Since the InteractionSourcePose is internal to UnityEngine.VR.WSA.Input, this is a fake InteractionSo...
static Camera Main
Returns a cached reference to the main camera and uses Camera.main if it hasn&#39;t been cached yet...
Definition: CameraCache.cs:20
Since the InteractionSourceState is internal to UnityEngine.VR.WSA.Input, this is a fake SourceState ...
Class for manually controlling inputs when running in the Unity editor.
AxisController uses the keyboard, mouse, or joystick and allows you to map a 1 axis controller to 1 a...