Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
19 KiB

  1. // Controller Tooltips|Prefabs|0070
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. /// <summary>
  6. /// Event Payload
  7. /// </summary>
  8. /// <param name="element">The tooltip element being affected.</param>
  9. public struct ControllerTooltipsEventArgs
  10. {
  11. public VRTK_ControllerTooltips.TooltipButtons element;
  12. }
  13. /// <summary>
  14. /// Event Payload
  15. /// </summary>
  16. /// <param name="sender">this object</param>
  17. /// <param name="e"><see cref="ControllerTooltipsEventArgs"/></param>
  18. public delegate void ControllerTooltipsEventHandler(object sender, ControllerTooltipsEventArgs e);
  19. /// <summary>
  20. /// Adds a collection of Object Tooltips to the Controller providing information to what the controller buttons may do.
  21. /// </summary>
  22. /// <remarks>
  23. /// **Prefab Usage:**
  24. /// * Place the `VRTK/Prefabs/ControllerTooltips/ControllerTooltips` prefab as a child of the relevant controller script alias GameObject in the scene hierarchy.
  25. /// * If no `Button Transform Settings` are provided in the inspector at Edit time then the button transforms will attempt to be set to the transforms of the current SDK default controller model.
  26. /// * If one of the `Button Text Settings` text options are not provided, then the tooltip for that specific button will be hidden.
  27. ///
  28. /// > There are a number of parameters that can be set on the Prefab which are provided by the `VRTK_ControllerTooltips` script which is applied to the prefab.
  29. /// </remarks>
  30. /// <example>
  31. /// `VRTK/Examples/029_Controller_Tooltips` displays two cubes that have an object tooltip added to them along with tooltips that have been added to the controllers.
  32. /// </example>
  33. public class VRTK_ControllerTooltips : MonoBehaviour
  34. {
  35. public enum TooltipButtons
  36. {
  37. None,
  38. TriggerTooltip,
  39. GripTooltip,
  40. TouchpadTooltip,
  41. TouchpadTwoTooltip,
  42. ButtonOneTooltip,
  43. ButtonTwoTooltip,
  44. StartMenuTooltip
  45. }
  46. [Header("Button Text Settings")]
  47. [Tooltip("The text to display for the trigger button action.")]
  48. public string triggerText;
  49. [Tooltip("The text to display for the grip button action.")]
  50. public string gripText;
  51. [Tooltip("The text to display for the touchpad action.")]
  52. public string touchpadText;
  53. [Tooltip("The text to display for the touchpad two action.")]
  54. public string touchpadTwoText;
  55. [Tooltip("The text to display for button one action.")]
  56. public string buttonOneText;
  57. [Tooltip("The text to display for button two action.")]
  58. public string buttonTwoText;
  59. [Tooltip("The text to display for the start menu action.")]
  60. public string startMenuText;
  61. [Header("Tooltip Colour Settings")]
  62. [Tooltip("The colour to use for the tooltip background container.")]
  63. public Color tipBackgroundColor = Color.black;
  64. [Tooltip("The colour to use for the text within the tooltip.")]
  65. public Color tipTextColor = Color.white;
  66. [Tooltip("The colour to use for the line between the tooltip and the relevant controller button.")]
  67. public Color tipLineColor = Color.black;
  68. [Header("Button Transform Settings")]
  69. [Tooltip("The transform for the position of the trigger button on the controller.")]
  70. public Transform trigger;
  71. [Tooltip("The transform for the position of the grip button on the controller.")]
  72. public Transform grip;
  73. [Tooltip("The transform for the position of the touchpad button on the controller.")]
  74. public Transform touchpad;
  75. [Tooltip("The transform for the position of the touchpad two button on the controller.")]
  76. public Transform touchpadTwo;
  77. [Tooltip("The transform for the position of button one on the controller.")]
  78. public Transform buttonOne;
  79. [Tooltip("The transform for the position of button two on the controller.")]
  80. public Transform buttonTwo;
  81. [Tooltip("The transform for the position of the start menu on the controller.")]
  82. public Transform startMenu;
  83. [Header("Custom Settings")]
  84. [Tooltip("The controller to read the controller events from. If this is blank then it will attempt to get a controller events script from the same or parent GameObject.")]
  85. public VRTK_ControllerEvents controllerEvents;
  86. [Tooltip("The headset controller aware script to use to see if the headset is looking at the controller. If this is blank then it will attempt to get a controller events script from the same or parent GameObject.")]
  87. public VRTK_HeadsetControllerAware headsetControllerAware;
  88. [Tooltip("If this is checked then the tooltips will be hidden when the headset is not looking at the controller.")]
  89. public bool hideWhenNotInView = true;
  90. [Header("Obsolete Settings")]
  91. [System.Obsolete("`VRTK_ControllerTooltips.retryInitMaxTries` has been deprecated as tooltip initialisation now uses the `VRTK_TrackedController.ControllerModelAvailable` event.")]
  92. [ObsoleteInspector]
  93. public int retryInitMaxTries = 10;
  94. [System.Obsolete("`VRTK_ControllerTooltips.retryInitCounter` has been deprecated as tooltip initialisation now uses the `VRTK_TrackedController.ControllerModelAvailable` event.")]
  95. [ObsoleteInspector]
  96. public float retryInitCounter = 0.1f;
  97. /// <summary>
  98. /// Emitted when the controller tooltip is turned on.
  99. /// </summary>
  100. public event ControllerTooltipsEventHandler ControllerTooltipOn;
  101. /// <summary>
  102. /// Emitted when the controller tooltip is turned off.
  103. /// </summary>
  104. public event ControllerTooltipsEventHandler ControllerTooltipOff;
  105. protected TooltipButtons[] availableButtons = new TooltipButtons[0];
  106. protected VRTK_ObjectTooltip[] buttonTooltips = new VRTK_ObjectTooltip[0];
  107. protected bool[] tooltipStates = new bool[0];
  108. protected bool overallState = true;
  109. protected VRTK_TrackedController trackedController;
  110. public virtual void OnControllerTooltipOn(ControllerTooltipsEventArgs e)
  111. {
  112. if (ControllerTooltipOn != null)
  113. {
  114. ControllerTooltipOn(this, e);
  115. }
  116. }
  117. public virtual void OnControllerTooltipOff(ControllerTooltipsEventArgs e)
  118. {
  119. if (ControllerTooltipOff != null)
  120. {
  121. ControllerTooltipOff(this, e);
  122. }
  123. }
  124. /// <summary>
  125. /// The Reset method reinitalises the tooltips on all of the controller elements.
  126. /// </summary>
  127. public virtual void ResetTooltip()
  128. {
  129. InitialiseTips();
  130. }
  131. /// <summary>
  132. /// The UpdateText method allows the tooltip text on a specific controller element to be updated at runtime.
  133. /// </summary>
  134. /// <param name="element">The specific controller element to change the tooltip text on.</param>
  135. /// <param name="newText">A string containing the text to update the tooltip to display.</param>
  136. public virtual void UpdateText(TooltipButtons element, string newText)
  137. {
  138. switch (element)
  139. {
  140. case TooltipButtons.ButtonOneTooltip:
  141. buttonOneText = newText;
  142. break;
  143. case TooltipButtons.ButtonTwoTooltip:
  144. buttonTwoText = newText;
  145. break;
  146. case TooltipButtons.StartMenuTooltip:
  147. startMenuText = newText;
  148. break;
  149. case TooltipButtons.GripTooltip:
  150. gripText = newText;
  151. break;
  152. case TooltipButtons.TouchpadTooltip:
  153. touchpadText = newText;
  154. break;
  155. case TooltipButtons.TouchpadTwoTooltip:
  156. touchpadTwoText = newText;
  157. break;
  158. case TooltipButtons.TriggerTooltip:
  159. triggerText = newText;
  160. break;
  161. }
  162. ResetTooltip();
  163. }
  164. /// <summary>
  165. /// The ToggleTips method will display the controller tooltips if the state is `true` and will hide the controller tooltips if the state is `false`. An optional `element` can be passed to target a specific controller tooltip to toggle otherwise all tooltips are toggled.
  166. /// </summary>
  167. /// <param name="state">The state of whether to display or hide the controller tooltips, true will display and false will hide.</param>
  168. /// <param name="element">The specific element to hide the tooltip on, if it is `TooltipButtons.None` then it will hide all tooltips. Optional parameter defaults to `TooltipButtons.None`</param>
  169. public virtual void ToggleTips(bool state, TooltipButtons element = TooltipButtons.None)
  170. {
  171. if (element == TooltipButtons.None)
  172. {
  173. overallState = state;
  174. for (int i = 1; i < buttonTooltips.Length; i++)
  175. {
  176. if (buttonTooltips[i].displayText.Length > 0)
  177. {
  178. buttonTooltips[i].gameObject.SetActive(state);
  179. }
  180. }
  181. }
  182. else
  183. {
  184. if (buttonTooltips[(int)element].displayText.Length > 0)
  185. {
  186. buttonTooltips[(int)element].gameObject.SetActive(state);
  187. }
  188. }
  189. EmitEvent(state, element);
  190. }
  191. protected virtual void Awake()
  192. {
  193. VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
  194. InitButtonsArray();
  195. }
  196. protected virtual void OnEnable()
  197. {
  198. controllerEvents = (controllerEvents != null ? controllerEvents : GetComponentInParent<VRTK_ControllerEvents>());
  199. InitButtonsArray();
  200. InitListeners();
  201. ResetTooltip();
  202. }
  203. protected virtual void OnDisable()
  204. {
  205. if (controllerEvents != null)
  206. {
  207. controllerEvents.ControllerEnabled -= DoControllerEnabled;
  208. controllerEvents.ControllerVisible -= DoControllerVisible;
  209. controllerEvents.ControllerHidden -= DoControllerInvisible;
  210. controllerEvents.ControllerModelAvailable -= DoControllerModelAvailable;
  211. }
  212. else if (trackedController != null)
  213. {
  214. trackedController.ControllerModelAvailable -= TrackedControllerDoControllerModelAvailable;
  215. }
  216. if (headsetControllerAware != null)
  217. {
  218. headsetControllerAware.ControllerGlanceEnter -= DoGlanceEnterController;
  219. headsetControllerAware.ControllerGlanceExit -= DoGlanceExitController;
  220. }
  221. }
  222. protected virtual void OnDestroy()
  223. {
  224. VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
  225. }
  226. protected virtual void EmitEvent(bool state, TooltipButtons element)
  227. {
  228. ControllerTooltipsEventArgs e;
  229. e.element = element;
  230. if (state)
  231. {
  232. OnControllerTooltipOn(e);
  233. }
  234. else
  235. {
  236. OnControllerTooltipOff(e);
  237. }
  238. }
  239. protected virtual void InitButtonsArray()
  240. {
  241. availableButtons = new TooltipButtons[]
  242. {
  243. TooltipButtons.None,
  244. TooltipButtons.TriggerTooltip,
  245. TooltipButtons.GripTooltip,
  246. TooltipButtons.TouchpadTooltip,
  247. TooltipButtons.TouchpadTwoTooltip,
  248. TooltipButtons.ButtonOneTooltip,
  249. TooltipButtons.ButtonTwoTooltip,
  250. TooltipButtons.StartMenuTooltip
  251. };
  252. buttonTooltips = new VRTK_ObjectTooltip[availableButtons.Length];
  253. tooltipStates = new bool[availableButtons.Length];
  254. for (int i = 1; i < availableButtons.Length; i++)
  255. {
  256. buttonTooltips[i] = transform.Find(availableButtons[i].ToString()).GetComponent<VRTK_ObjectTooltip>();
  257. }
  258. }
  259. protected virtual void InitListeners()
  260. {
  261. if (controllerEvents != null)
  262. {
  263. controllerEvents.ControllerEnabled += DoControllerEnabled;
  264. controllerEvents.ControllerVisible += DoControllerVisible;
  265. controllerEvents.ControllerHidden += DoControllerInvisible;
  266. controllerEvents.ControllerModelAvailable += DoControllerModelAvailable;
  267. }
  268. else
  269. {
  270. trackedController = GetComponentInParent<VRTK_TrackedController>();
  271. if (trackedController != null)
  272. {
  273. trackedController.ControllerModelAvailable += TrackedControllerDoControllerModelAvailable;
  274. }
  275. }
  276. headsetControllerAware = (headsetControllerAware != null ? headsetControllerAware : FindObjectOfType<VRTK_HeadsetControllerAware>());
  277. if (headsetControllerAware != null)
  278. {
  279. headsetControllerAware.ControllerGlanceEnter += DoGlanceEnterController;
  280. headsetControllerAware.ControllerGlanceExit += DoGlanceExitController;
  281. ToggleTips(false);
  282. }
  283. }
  284. protected virtual void DoControllerEnabled(object sender, ControllerInteractionEventArgs e)
  285. {
  286. if (controllerEvents != null)
  287. {
  288. GameObject actualController = VRTK_DeviceFinder.GetActualController(controllerEvents.gameObject);
  289. if (actualController != null && actualController.activeInHierarchy)
  290. {
  291. ResetTooltip();
  292. }
  293. }
  294. }
  295. protected virtual void DoControllerVisible(object sender, ControllerInteractionEventArgs e)
  296. {
  297. for (int i = 0; i < availableButtons.Length; i++)
  298. {
  299. ToggleTips(tooltipStates[i], availableButtons[i]);
  300. }
  301. }
  302. protected virtual void DoControllerInvisible(object sender, ControllerInteractionEventArgs e)
  303. {
  304. for (int i = 1; i < buttonTooltips.Length; i++)
  305. {
  306. tooltipStates[i] = buttonTooltips[i].gameObject.activeSelf;
  307. }
  308. ToggleTips(false);
  309. }
  310. protected virtual void DoControllerModelAvailable(object sender, ControllerInteractionEventArgs e)
  311. {
  312. ResetTooltip();
  313. }
  314. protected virtual void TrackedControllerDoControllerModelAvailable(object sender, VRTKTrackedControllerEventArgs e)
  315. {
  316. ResetTooltip();
  317. }
  318. protected virtual void DoGlanceEnterController(object sender, HeadsetControllerAwareEventArgs e)
  319. {
  320. if (controllerEvents != null && hideWhenNotInView)
  321. {
  322. VRTK_ControllerReference checkControllerReference = VRTK_ControllerReference.GetControllerReference(controllerEvents.gameObject);
  323. if (checkControllerReference == e.controllerReference)
  324. {
  325. ToggleTips(true);
  326. }
  327. }
  328. }
  329. protected virtual void DoGlanceExitController(object sender, HeadsetControllerAwareEventArgs e)
  330. {
  331. if (controllerEvents != null && hideWhenNotInView)
  332. {
  333. VRTK_ControllerReference checkControllerReference = VRTK_ControllerReference.GetControllerReference(controllerEvents.gameObject);
  334. if (checkControllerReference == e.controllerReference)
  335. {
  336. ToggleTips(false);
  337. }
  338. }
  339. }
  340. protected virtual void InitialiseTips()
  341. {
  342. VRTK_ObjectTooltip[] tooltips = GetComponentsInChildren<VRTK_ObjectTooltip>(true);
  343. for (int i = 0; i < tooltips.Length; i++)
  344. {
  345. VRTK_ObjectTooltip tooltip = tooltips[i];
  346. string tipText = "";
  347. Transform tipTransform = null;
  348. switch (tooltip.name.Replace("Tooltip", "").ToLower())
  349. {
  350. case "trigger":
  351. tipText = triggerText;
  352. tipTransform = GetTransform(trigger, SDK_BaseController.ControllerElements.Trigger);
  353. break;
  354. case "grip":
  355. tipText = gripText;
  356. tipTransform = GetTransform(grip, SDK_BaseController.ControllerElements.GripLeft);
  357. break;
  358. case "touchpad":
  359. tipText = touchpadText;
  360. tipTransform = GetTransform(touchpad, SDK_BaseController.ControllerElements.Touchpad);
  361. break;
  362. case "touchpadtwo":
  363. tipText = touchpadTwoText;
  364. tipTransform = GetTransform(touchpadTwo, SDK_BaseController.ControllerElements.TouchpadTwo);
  365. break;
  366. case "buttonone":
  367. tipText = buttonOneText;
  368. tipTransform = GetTransform(buttonOne, SDK_BaseController.ControllerElements.ButtonOne);
  369. break;
  370. case "buttontwo":
  371. tipText = buttonTwoText;
  372. tipTransform = GetTransform(buttonTwo, SDK_BaseController.ControllerElements.ButtonTwo);
  373. break;
  374. case "startmenu":
  375. tipText = startMenuText;
  376. tipTransform = GetTransform(startMenu, SDK_BaseController.ControllerElements.StartMenu);
  377. break;
  378. }
  379. tooltip.displayText = tipText;
  380. tooltip.drawLineTo = tipTransform;
  381. tooltip.containerColor = tipBackgroundColor;
  382. tooltip.fontColor = tipTextColor;
  383. tooltip.lineColor = tipLineColor;
  384. tooltip.ResetTooltip();
  385. if (tipTransform == null || tipText.Trim().Length == 0)
  386. {
  387. tooltip.gameObject.SetActive(false);
  388. }
  389. }
  390. if (headsetControllerAware == null || !hideWhenNotInView)
  391. {
  392. ToggleTips(overallState);
  393. }
  394. }
  395. protected virtual Transform GetTransform(Transform setTransform, SDK_BaseController.ControllerElements findElement)
  396. {
  397. Transform returnTransform = null;
  398. if (setTransform != null)
  399. {
  400. returnTransform = setTransform;
  401. }
  402. else if (controllerEvents != null)
  403. {
  404. GameObject modelController = VRTK_DeviceFinder.GetModelAliasController(controllerEvents.gameObject);
  405. if (modelController != null && modelController.activeInHierarchy)
  406. {
  407. SDK_BaseController.ControllerHand controllerHand = VRTK_DeviceFinder.GetControllerHand(controllerEvents.gameObject);
  408. string elementPath = VRTK_SDK_Bridge.GetControllerElementPath(findElement, controllerHand, true);
  409. returnTransform = (elementPath != null ? modelController.transform.Find(elementPath) : null);
  410. }
  411. }
  412. return returnTransform;
  413. }
  414. }
  415. }