Tilt Five™ Unity API  1.3.0
 
Loading...
Searching...
No Matches
Input.cs
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020-2022 Tilt Five, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16using System;
17using UnityEngine;
18
19#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
20using UnityEngine.InputSystem;
21#endif
22
24
25namespace TiltFive
26{
30 public static class Input
31 {
32 #region Public Enums
33
34 public enum WandButton : UInt32
35 {
36 T5 = 1 << 0,
37 One = 1 << 1,
38 Two = 1 << 2,
39 Three = 1 << 7,
40 Y = 1 << 3,
41 B = 1 << 4,
42 A = 1 << 5,
43 X = 1 << 6,
44 [Obsolete("WandButton.System is deprecated, please use Wandbutton.T5 instead.")]
45 System = T5,
46 [Obsolete("WandButton.Z is deprecated, please use Wandbutton.Three instead.")]
47 Z = Three,
48 }
49
50 #endregion Public Enums
51
52
53 #region Private Fields
54
55#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
56 internal static GlassesDevice[] glassesDevices = new GlassesDevice[PlayerSettings.MAX_SUPPORTED_PLAYERS];
57 internal static WandDevice[,] wandDevices = new WandDevice[PlayerSettings.MAX_SUPPORTED_PLAYERS, 2];
58#endif
59
60 #endregion
61
62
63 #region Public Functions
64
74 public static bool GetButton(WandButton button,
75 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
76 {
77 return TryGetButton(button, out var pressed, controllerIndex, playerIndex) && pressed;
78 }
79
89 public static bool TryGetButton(WandButton button, out bool pressed,
90 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
91 {
92 if(!Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
93 {
94 pressed = false;
95 return false;
96 }
97
98 return Wand.TryGetButton(button, out pressed, glassesHandle, controllerIndex);
99 }
100
109 public static bool GetButtonDown(WandButton button,
110 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
111 {
112 return TryGetButtonDown(button, out var buttonDown, controllerIndex, playerIndex) && buttonDown;
113 }
114
124 public static bool TryGetButtonDown(WandButton button, out bool buttonDown,
125 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
126 {
127 // The specified player's glasses aren't even connected, let alone the wand. No way to get a rising edge here.
128 if(!Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
129 {
130 buttonDown = false;
131 return false;
132 }
133
134 return Wand.TryGetButtonDown(button, out buttonDown, glassesHandle, controllerIndex);
135 }
136
144 public static bool GetButtonUp(WandButton button,
145 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
146 {
147 return TryGetButtonUp(button, out var buttonUp, controllerIndex, playerIndex) && buttonUp;
148 }
149
160 public static bool TryGetButtonUp(WandButton button, out bool buttonUp,
161 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
162 {
163 // TODO: Tweak the Wand.cs TryGetButtonDown to check if the glasses disconnected this frame.
164 // If it did, and the button was held last frame, then buttonUp can be true.
165 if(!Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
166 {
167 buttonUp = false;
168 return false;
169 }
170
171 return Wand.TryGetButtonUp(button, out buttonUp, glassesHandle, controllerIndex);
172 }
173
180 public static Vector2 GetStickTilt(ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
181 {
182 if(TryGetStickTilt(out var stickTilt, controllerIndex, playerIndex))
183 {
184 return stickTilt;
185 }
186 return Vector2.zero;
187 }
188
196 public static bool TryGetStickTilt(out Vector2 stickTilt,
197 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
198 {
199 if(!Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
200 {
201 stickTilt = Vector2.zero;
202 return false;
203 }
204 return Wand.TryGetStickTilt(out stickTilt, glassesHandle, controllerIndex);
205 }
206
214 public static float GetTrigger(ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
215 {
216 if(TryGetTrigger(out var triggerDisplacement, controllerIndex, playerIndex))
217 {
218 return triggerDisplacement;
219 }
220 return 0f;
221 }
222
231 public static bool TryGetTrigger(out float triggerDisplacement,
232 ControllerIndex controllerIndex = ControllerIndex.Right, PlayerIndex playerIndex = PlayerIndex.One)
233 {
234 if (!Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
235 {
236 triggerDisplacement = 0f;
237 return false;
238 }
239 return Wand.TryGetTrigger(out triggerDisplacement, glassesHandle, controllerIndex);
240 }
241
247 public static bool GetWandAvailability(ControllerIndex controllerIndex = ControllerIndex.Right)
248 {
249 return Wand.TryCheckConnected(out var connected, PlayerIndex.One, controllerIndex) && connected;
250 }
251
252 // Legacy code, might remove soon.
253 public static bool SetRumbleMotor(uint motor, float intensity)
254 {
255
256 int result = 0;
257 try
258 {
259 result = NativePlugin.SetRumbleMotor(motor, intensity);
260 }
261 catch (Exception e)
262 {
263 Log.Error(e.Message);
264 }
265
266 return (0 != result);
267 }
268
269 public static void Update()
270 {
271 // Deleting this function would be appropriate, but since it's public,
272 // there's a small chance it could break someone's code...
273 // ...not that I can think of a use-case that involves calling TiltFive.Input.Update()
274 }
275
276 #endregion Public Functions
277
278
279 #region Internal Functions
280
281 internal static bool GetButton(this T5_ControllerState controllerState, WandButton button)
282 {
283 var buttonsState = controllerState.ButtonsState;
284
285 switch (button)
286 {
287 case WandButton.T5:
288 return buttonsState.T5;
289 case WandButton.One:
290 return buttonsState.One;
291 case WandButton.Two:
292 return buttonsState.Two;
293 case WandButton.Y:
294 return buttonsState.Y;
295 case WandButton.B:
296 return buttonsState.B;
297 case WandButton.A:
298 return buttonsState.A;
299 case WandButton.X:
300 return buttonsState.X;
301 case WandButton.Three:
302 return buttonsState.Three;
303 default:
304 throw new ArgumentException("Invalid WandButton argument - enum value does not exist");
305 }
306
307 }
308
309 internal static bool TryGetButton(this T5_ControllerState controllerState, WandButton button)
310 {
311 return controllerState.ButtonsValid && controllerState.GetButton(button);
312 }
313
314 internal static Vector2 TryGetStick(this T5_ControllerState controllerState)
315 {
316 return controllerState.AnalogValid ? controllerState.Stick : Vector2.zero;
317 }
318
319 internal static float TryGetTrigger(this T5_ControllerState controllerState)
320 {
321 return controllerState.AnalogValid ? controllerState.Trigger : 0f;
322 }
323
324#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
325 internal static GlassesDevice GetGlassesDevice(PlayerIndex playerIndex)
326 {
327 return glassesDevices[(int)playerIndex - 1];
328 }
329
330 internal static WandDevice GetWandDevice(PlayerIndex playerIndex, ControllerIndex controllerIndex)
331 {
332 return wandDevices[(int)playerIndex - 1, (int)controllerIndex];
333 }
334#endif
335
336 #endregion Internal Functions
337
338
339 #region Private Functions
340
341 static Input()
342 {
344 }
345
346#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
347 internal static void AddGlassesDevice(PlayerIndex playerIndex)
348 {
349 var glassesDevices = Input.glassesDevices;
350 int i = (int)playerIndex - 1;
351
352 // Create a GlassesDevice if necessary
353 if (glassesDevices[i] == null)
354 {
355 var preexistingGlassesDevice = InputSystem.GetDevice<GlassesDevice>($"Player{playerIndex}");
356 if (preexistingGlassesDevice != null)
357 {
358 glassesDevices[i] = preexistingGlassesDevice;
359 glassesDevices[i].PlayerIndex = playerIndex;
360 }
361 else
362 {
363 glassesDevices[i] = InputSystem.AddDevice<GlassesDevice>($"T5 Glasses - Player {playerIndex}");
364 glassesDevices[i].PlayerIndex = playerIndex;
365 InputSystem.AddDeviceUsage(glassesDevices[i], $"Player{playerIndex}");
366 }
367
368 }
369 else if (!glassesDevices[i].added)
370 {
371 InputSystem.AddDevice(glassesDevices[i]);
372 }
373 }
374
375 internal static void AddWandDevice(PlayerIndex playerIndex, ControllerIndex controllerIndex)
376 {
377 var wandDevices = Input.wandDevices;
378 int i = (int)playerIndex - 1;
379 int j = (int)controllerIndex;
380
381 // Unfortunately, the enum ControllerIndex.Primary still exists, and Unity seems to have a habit
382 // of substituting its display name when we're trying to get the display name for ControllerIndex.Right.
383 // TODO: Localize
384 var handednessLabel = controllerIndex == ControllerIndex.Right ? "Right" : "Left";
385
386 // If we already know about a wandDevice corresponding to our input parameters, add it to the input system if it isn't already added
387 if (wandDevices[i, j] != null && !wandDevices[i, j].added)
388 {
389 var wandDevice = wandDevices[i, j];
390 InputSystem.AddDevice(wandDevice);
391 wandDevice.ControllerIndex = controllerIndex;
392 InputSystem.QueueConfigChangeEvent(wandDevice);
393 InputSystem.AddDevice(wandDevice);
394 }
395 else
396 {
397 // Otherwise, ask the input system if it has a matching wandDevice.
398 // This corner case (in which a matching wandDevice exists, but the static field in Player.cs is empty)
399 // can occur when reloading scripts. Unity's input system keeps the device alive, but this class suffers amnesia.
400 WandDevice currentWandDevice = InputSystem.GetDevice<WandDevice>($"Player{playerIndex}-{handednessLabel}Hand");
401
402 // If the input system does have a matching wandDevice, just remember it and we're done
403 if (currentWandDevice != null)
404 {
405 wandDevices[i, j] = currentWandDevice;
406 }
407 // Otherwise, add a brand new wandDevice to the input system and remember it.
408 else
409 {
410 wandDevices[i, j] = InputSystem.AddDevice<WandDevice>($"T5 Wand - P{(int)playerIndex} {handednessLabel}");
411 }
412
413 wandDevices[i, j].playerIndex = playerIndex;
414 wandDevices[i, j].ControllerIndex = controllerIndex;
415 InputSystem.AddDeviceUsage(wandDevices[i, j], $"Player{playerIndex}");
416 InputSystem.AddDeviceUsage(wandDevices[i, j], $"Player{playerIndex}-{handednessLabel}Hand");
417 InputSystem.QueueConfigChangeEvent(wandDevices[i, j]);
418 }
419 }
420#endif
421
422 #endregion Private Functions
423 }
424
425}
TiltFive.Input.WandButton WandButton
Definition: Wand.cs:28
Provides access to Wand inputs.
Definition: Input.cs:31
static bool TryGetButtonDown(WandButton button, out bool buttonDown, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button was pressed during this frame. Fails if the wand is unavailable.
Definition: Input.cs:124
static bool TryGetTrigger(out float triggerDisplacement, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Gets the degree to which the trigger is depressed, from 0.0 (released) to 1.0 (fully depressed)....
Definition: Input.cs:231
static bool TryGetButtonUp(WandButton button, out bool buttonUp, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button was released during this frame. Fails if the wand is unavailable.
Definition: Input.cs:160
static Vector2 GetStickTilt(ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Gets the direction and magnitude of the stick's tilt for the indicated wand.
Definition: Input.cs:180
static Input()
Definition: Input.cs:341
static bool GetButtonDown(WandButton button, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button was pressed during this frame.
Definition: Input.cs:109
static bool TryGetStickTilt(out Vector2 stickTilt, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Gets the direction and magnitude of the stick's tilt for the indicated wand. Fails if the wand is una...
Definition: Input.cs:196
static bool GetButton(WandButton button, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button is currently being pressed.
Definition: Input.cs:74
static void Update()
Definition: Input.cs:269
static bool SetRumbleMotor(uint motor, float intensity)
Definition: Input.cs:253
static bool TryGetButton(WandButton button, out bool pressed, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button is currently being pressed. Fails if the wand is unavailable.
Definition: Input.cs:89
static bool GetWandAvailability(ControllerIndex controllerIndex=ControllerIndex.Right)
Gets the connection status of the indicated wand.
Definition: Input.cs:247
static float GetTrigger(ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Gets the degree to which the trigger is depressed, from 0.0 (released) to 1.0 (fully depressed).
Definition: Input.cs:214
static bool GetButtonUp(WandButton button, ControllerIndex controllerIndex=ControllerIndex.Right, PlayerIndex playerIndex=PlayerIndex.One)
Whether the indicated wand button was released during this frame.
Definition: Input.cs:144
The Logger.
Definition: Log.cs:42
static void Error(string m, params object[] list)
ERROR logging function call.
Definition: Log.cs:127
static int SetRumbleMotor(uint motor, float intensity)
Provides access to player settings and functionality.
Definition: Player.cs:16
static uint MAX_SUPPORTED_PLAYERS
The Wand API and runtime.
Definition: Wand.cs:56
static bool TryCheckConnected(out bool connected, PlayerIndex playerIndex, ControllerIndex controllerIndex=ControllerIndex.Right)
Gets the connection status of the indicated wand.
Definition: Wand.cs:366
static void ScanForWands()
Definition: Wand.cs:204
Definition: Log.cs:21
ControllerIndex
Since wands are all physically identical (they have no "handedness"), it doesn't make sense to addres...
PlayerIndex
The Player index (e.g. Player One, Player Two, etc)
Contains wand related information (Pose, Buttons, Trigger, Stick, Battery)