// Controller Tooltips|Prefabs|0070
|
|
namespace VRTK
|
|
{
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Event Payload
|
|
/// </summary>
|
|
/// <param name="element">The tooltip element being affected.</param>
|
|
public struct ControllerTooltipsEventArgs
|
|
{
|
|
public VRTK_ControllerTooltips.TooltipButtons element;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event Payload
|
|
/// </summary>
|
|
/// <param name="sender">this object</param>
|
|
/// <param name="e"><see cref="ControllerTooltipsEventArgs"/></param>
|
|
public delegate void ControllerTooltipsEventHandler(object sender, ControllerTooltipsEventArgs e);
|
|
|
|
/// <summary>
|
|
/// Adds a collection of Object Tooltips to the Controller providing information to what the controller buttons may do.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// **Prefab Usage:**
|
|
/// * Place the `VRTK/Prefabs/ControllerTooltips/ControllerTooltips` prefab as a child of the relevant controller script alias GameObject in the scene hierarchy.
|
|
/// * 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.
|
|
/// * If one of the `Button Text Settings` text options are not provided, then the tooltip for that specific button will be hidden.
|
|
///
|
|
/// > 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.
|
|
/// </remarks>
|
|
/// <example>
|
|
/// `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.
|
|
/// </example>
|
|
public class VRTK_ControllerTooltips : MonoBehaviour
|
|
{
|
|
public enum TooltipButtons
|
|
{
|
|
None,
|
|
TriggerTooltip,
|
|
GripTooltip,
|
|
TouchpadTooltip,
|
|
TouchpadTwoTooltip,
|
|
ButtonOneTooltip,
|
|
ButtonTwoTooltip,
|
|
StartMenuTooltip
|
|
}
|
|
|
|
[Header("Button Text Settings")]
|
|
|
|
[Tooltip("The text to display for the trigger button action.")]
|
|
public string triggerText;
|
|
[Tooltip("The text to display for the grip button action.")]
|
|
public string gripText;
|
|
[Tooltip("The text to display for the touchpad action.")]
|
|
public string touchpadText;
|
|
[Tooltip("The text to display for the touchpad two action.")]
|
|
public string touchpadTwoText;
|
|
[Tooltip("The text to display for button one action.")]
|
|
public string buttonOneText;
|
|
[Tooltip("The text to display for button two action.")]
|
|
public string buttonTwoText;
|
|
[Tooltip("The text to display for the start menu action.")]
|
|
public string startMenuText;
|
|
|
|
[Header("Tooltip Colour Settings")]
|
|
|
|
[Tooltip("The colour to use for the tooltip background container.")]
|
|
public Color tipBackgroundColor = Color.black;
|
|
[Tooltip("The colour to use for the text within the tooltip.")]
|
|
public Color tipTextColor = Color.white;
|
|
[Tooltip("The colour to use for the line between the tooltip and the relevant controller button.")]
|
|
public Color tipLineColor = Color.black;
|
|
|
|
[Header("Button Transform Settings")]
|
|
|
|
[Tooltip("The transform for the position of the trigger button on the controller.")]
|
|
public Transform trigger;
|
|
[Tooltip("The transform for the position of the grip button on the controller.")]
|
|
public Transform grip;
|
|
[Tooltip("The transform for the position of the touchpad button on the controller.")]
|
|
public Transform touchpad;
|
|
[Tooltip("The transform for the position of the touchpad two button on the controller.")]
|
|
public Transform touchpadTwo;
|
|
[Tooltip("The transform for the position of button one on the controller.")]
|
|
public Transform buttonOne;
|
|
[Tooltip("The transform for the position of button two on the controller.")]
|
|
public Transform buttonTwo;
|
|
[Tooltip("The transform for the position of the start menu on the controller.")]
|
|
public Transform startMenu;
|
|
|
|
[Header("Custom Settings")]
|
|
|
|
[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.")]
|
|
public VRTK_ControllerEvents controllerEvents;
|
|
[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.")]
|
|
public VRTK_HeadsetControllerAware headsetControllerAware;
|
|
[Tooltip("If this is checked then the tooltips will be hidden when the headset is not looking at the controller.")]
|
|
public bool hideWhenNotInView = true;
|
|
|
|
[Header("Obsolete Settings")]
|
|
|
|
[System.Obsolete("`VRTK_ControllerTooltips.retryInitMaxTries` has been deprecated as tooltip initialisation now uses the `VRTK_TrackedController.ControllerModelAvailable` event.")]
|
|
[ObsoleteInspector]
|
|
public int retryInitMaxTries = 10;
|
|
[System.Obsolete("`VRTK_ControllerTooltips.retryInitCounter` has been deprecated as tooltip initialisation now uses the `VRTK_TrackedController.ControllerModelAvailable` event.")]
|
|
[ObsoleteInspector]
|
|
public float retryInitCounter = 0.1f;
|
|
|
|
/// <summary>
|
|
/// Emitted when the controller tooltip is turned on.
|
|
/// </summary>
|
|
public event ControllerTooltipsEventHandler ControllerTooltipOn;
|
|
/// <summary>
|
|
/// Emitted when the controller tooltip is turned off.
|
|
/// </summary>
|
|
public event ControllerTooltipsEventHandler ControllerTooltipOff;
|
|
|
|
protected TooltipButtons[] availableButtons = new TooltipButtons[0];
|
|
protected VRTK_ObjectTooltip[] buttonTooltips = new VRTK_ObjectTooltip[0];
|
|
protected bool[] tooltipStates = new bool[0];
|
|
protected bool overallState = true;
|
|
protected VRTK_TrackedController trackedController;
|
|
|
|
public virtual void OnControllerTooltipOn(ControllerTooltipsEventArgs e)
|
|
{
|
|
if (ControllerTooltipOn != null)
|
|
{
|
|
ControllerTooltipOn(this, e);
|
|
}
|
|
}
|
|
|
|
public virtual void OnControllerTooltipOff(ControllerTooltipsEventArgs e)
|
|
{
|
|
if (ControllerTooltipOff != null)
|
|
{
|
|
ControllerTooltipOff(this, e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The Reset method reinitalises the tooltips on all of the controller elements.
|
|
/// </summary>
|
|
public virtual void ResetTooltip()
|
|
{
|
|
InitialiseTips();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The UpdateText method allows the tooltip text on a specific controller element to be updated at runtime.
|
|
/// </summary>
|
|
/// <param name="element">The specific controller element to change the tooltip text on.</param>
|
|
/// <param name="newText">A string containing the text to update the tooltip to display.</param>
|
|
public virtual void UpdateText(TooltipButtons element, string newText)
|
|
{
|
|
switch (element)
|
|
{
|
|
case TooltipButtons.ButtonOneTooltip:
|
|
buttonOneText = newText;
|
|
break;
|
|
case TooltipButtons.ButtonTwoTooltip:
|
|
buttonTwoText = newText;
|
|
break;
|
|
case TooltipButtons.StartMenuTooltip:
|
|
startMenuText = newText;
|
|
break;
|
|
case TooltipButtons.GripTooltip:
|
|
gripText = newText;
|
|
break;
|
|
case TooltipButtons.TouchpadTooltip:
|
|
touchpadText = newText;
|
|
break;
|
|
case TooltipButtons.TouchpadTwoTooltip:
|
|
touchpadTwoText = newText;
|
|
break;
|
|
case TooltipButtons.TriggerTooltip:
|
|
triggerText = newText;
|
|
break;
|
|
}
|
|
ResetTooltip();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="state">The state of whether to display or hide the controller tooltips, true will display and false will hide.</param>
|
|
/// <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>
|
|
public virtual void ToggleTips(bool state, TooltipButtons element = TooltipButtons.None)
|
|
{
|
|
if (element == TooltipButtons.None)
|
|
{
|
|
overallState = state;
|
|
for (int i = 1; i < buttonTooltips.Length; i++)
|
|
{
|
|
if (buttonTooltips[i].displayText.Length > 0)
|
|
{
|
|
buttonTooltips[i].gameObject.SetActive(state);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (buttonTooltips[(int)element].displayText.Length > 0)
|
|
{
|
|
buttonTooltips[(int)element].gameObject.SetActive(state);
|
|
}
|
|
}
|
|
EmitEvent(state, element);
|
|
}
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
|
|
InitButtonsArray();
|
|
}
|
|
|
|
protected virtual void OnEnable()
|
|
{
|
|
controllerEvents = (controllerEvents != null ? controllerEvents : GetComponentInParent<VRTK_ControllerEvents>());
|
|
InitButtonsArray();
|
|
InitListeners();
|
|
ResetTooltip();
|
|
}
|
|
|
|
protected virtual void OnDisable()
|
|
{
|
|
if (controllerEvents != null)
|
|
{
|
|
controllerEvents.ControllerEnabled -= DoControllerEnabled;
|
|
controllerEvents.ControllerVisible -= DoControllerVisible;
|
|
controllerEvents.ControllerHidden -= DoControllerInvisible;
|
|
controllerEvents.ControllerModelAvailable -= DoControllerModelAvailable;
|
|
}
|
|
else if (trackedController != null)
|
|
{
|
|
trackedController.ControllerModelAvailable -= TrackedControllerDoControllerModelAvailable;
|
|
}
|
|
|
|
if (headsetControllerAware != null)
|
|
{
|
|
headsetControllerAware.ControllerGlanceEnter -= DoGlanceEnterController;
|
|
headsetControllerAware.ControllerGlanceExit -= DoGlanceExitController;
|
|
}
|
|
}
|
|
|
|
protected virtual void OnDestroy()
|
|
{
|
|
VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
|
|
}
|
|
|
|
protected virtual void EmitEvent(bool state, TooltipButtons element)
|
|
{
|
|
ControllerTooltipsEventArgs e;
|
|
e.element = element;
|
|
if (state)
|
|
{
|
|
OnControllerTooltipOn(e);
|
|
}
|
|
else
|
|
{
|
|
OnControllerTooltipOff(e);
|
|
}
|
|
}
|
|
|
|
protected virtual void InitButtonsArray()
|
|
{
|
|
availableButtons = new TooltipButtons[]
|
|
{
|
|
TooltipButtons.None,
|
|
TooltipButtons.TriggerTooltip,
|
|
TooltipButtons.GripTooltip,
|
|
TooltipButtons.TouchpadTooltip,
|
|
TooltipButtons.TouchpadTwoTooltip,
|
|
TooltipButtons.ButtonOneTooltip,
|
|
TooltipButtons.ButtonTwoTooltip,
|
|
TooltipButtons.StartMenuTooltip
|
|
};
|
|
|
|
buttonTooltips = new VRTK_ObjectTooltip[availableButtons.Length];
|
|
tooltipStates = new bool[availableButtons.Length];
|
|
|
|
for (int i = 1; i < availableButtons.Length; i++)
|
|
{
|
|
buttonTooltips[i] = transform.Find(availableButtons[i].ToString()).GetComponent<VRTK_ObjectTooltip>();
|
|
}
|
|
}
|
|
|
|
protected virtual void InitListeners()
|
|
{
|
|
if (controllerEvents != null)
|
|
{
|
|
controllerEvents.ControllerEnabled += DoControllerEnabled;
|
|
controllerEvents.ControllerVisible += DoControllerVisible;
|
|
controllerEvents.ControllerHidden += DoControllerInvisible;
|
|
controllerEvents.ControllerModelAvailable += DoControllerModelAvailable;
|
|
}
|
|
else
|
|
{
|
|
trackedController = GetComponentInParent<VRTK_TrackedController>();
|
|
if (trackedController != null)
|
|
{
|
|
trackedController.ControllerModelAvailable += TrackedControllerDoControllerModelAvailable;
|
|
}
|
|
}
|
|
|
|
headsetControllerAware = (headsetControllerAware != null ? headsetControllerAware : FindObjectOfType<VRTK_HeadsetControllerAware>());
|
|
if (headsetControllerAware != null)
|
|
{
|
|
headsetControllerAware.ControllerGlanceEnter += DoGlanceEnterController;
|
|
headsetControllerAware.ControllerGlanceExit += DoGlanceExitController;
|
|
ToggleTips(false);
|
|
}
|
|
}
|
|
|
|
protected virtual void DoControllerEnabled(object sender, ControllerInteractionEventArgs e)
|
|
{
|
|
if (controllerEvents != null)
|
|
{
|
|
GameObject actualController = VRTK_DeviceFinder.GetActualController(controllerEvents.gameObject);
|
|
if (actualController != null && actualController.activeInHierarchy)
|
|
{
|
|
ResetTooltip();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void DoControllerVisible(object sender, ControllerInteractionEventArgs e)
|
|
{
|
|
for (int i = 0; i < availableButtons.Length; i++)
|
|
{
|
|
ToggleTips(tooltipStates[i], availableButtons[i]);
|
|
}
|
|
}
|
|
|
|
protected virtual void DoControllerInvisible(object sender, ControllerInteractionEventArgs e)
|
|
{
|
|
for (int i = 1; i < buttonTooltips.Length; i++)
|
|
{
|
|
tooltipStates[i] = buttonTooltips[i].gameObject.activeSelf;
|
|
}
|
|
ToggleTips(false);
|
|
}
|
|
|
|
protected virtual void DoControllerModelAvailable(object sender, ControllerInteractionEventArgs e)
|
|
{
|
|
ResetTooltip();
|
|
}
|
|
|
|
|
|
protected virtual void TrackedControllerDoControllerModelAvailable(object sender, VRTKTrackedControllerEventArgs e)
|
|
{
|
|
ResetTooltip();
|
|
}
|
|
|
|
protected virtual void DoGlanceEnterController(object sender, HeadsetControllerAwareEventArgs e)
|
|
{
|
|
if (controllerEvents != null && hideWhenNotInView)
|
|
{
|
|
VRTK_ControllerReference checkControllerReference = VRTK_ControllerReference.GetControllerReference(controllerEvents.gameObject);
|
|
if (checkControllerReference == e.controllerReference)
|
|
{
|
|
ToggleTips(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void DoGlanceExitController(object sender, HeadsetControllerAwareEventArgs e)
|
|
{
|
|
if (controllerEvents != null && hideWhenNotInView)
|
|
{
|
|
VRTK_ControllerReference checkControllerReference = VRTK_ControllerReference.GetControllerReference(controllerEvents.gameObject);
|
|
if (checkControllerReference == e.controllerReference)
|
|
{
|
|
ToggleTips(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void InitialiseTips()
|
|
{
|
|
VRTK_ObjectTooltip[] tooltips = GetComponentsInChildren<VRTK_ObjectTooltip>(true);
|
|
for (int i = 0; i < tooltips.Length; i++)
|
|
{
|
|
VRTK_ObjectTooltip tooltip = tooltips[i];
|
|
string tipText = "";
|
|
Transform tipTransform = null;
|
|
|
|
switch (tooltip.name.Replace("Tooltip", "").ToLower())
|
|
{
|
|
case "trigger":
|
|
tipText = triggerText;
|
|
tipTransform = GetTransform(trigger, SDK_BaseController.ControllerElements.Trigger);
|
|
break;
|
|
case "grip":
|
|
tipText = gripText;
|
|
tipTransform = GetTransform(grip, SDK_BaseController.ControllerElements.GripLeft);
|
|
break;
|
|
case "touchpad":
|
|
tipText = touchpadText;
|
|
tipTransform = GetTransform(touchpad, SDK_BaseController.ControllerElements.Touchpad);
|
|
break;
|
|
case "touchpadtwo":
|
|
tipText = touchpadTwoText;
|
|
tipTransform = GetTransform(touchpadTwo, SDK_BaseController.ControllerElements.TouchpadTwo);
|
|
break;
|
|
case "buttonone":
|
|
tipText = buttonOneText;
|
|
tipTransform = GetTransform(buttonOne, SDK_BaseController.ControllerElements.ButtonOne);
|
|
break;
|
|
case "buttontwo":
|
|
tipText = buttonTwoText;
|
|
tipTransform = GetTransform(buttonTwo, SDK_BaseController.ControllerElements.ButtonTwo);
|
|
break;
|
|
case "startmenu":
|
|
tipText = startMenuText;
|
|
tipTransform = GetTransform(startMenu, SDK_BaseController.ControllerElements.StartMenu);
|
|
break;
|
|
}
|
|
|
|
tooltip.displayText = tipText;
|
|
tooltip.drawLineTo = tipTransform;
|
|
|
|
tooltip.containerColor = tipBackgroundColor;
|
|
tooltip.fontColor = tipTextColor;
|
|
tooltip.lineColor = tipLineColor;
|
|
|
|
tooltip.ResetTooltip();
|
|
|
|
if (tipTransform == null || tipText.Trim().Length == 0)
|
|
{
|
|
tooltip.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
if (headsetControllerAware == null || !hideWhenNotInView)
|
|
{
|
|
ToggleTips(overallState);
|
|
}
|
|
}
|
|
|
|
protected virtual Transform GetTransform(Transform setTransform, SDK_BaseController.ControllerElements findElement)
|
|
{
|
|
Transform returnTransform = null;
|
|
if (setTransform != null)
|
|
{
|
|
returnTransform = setTransform;
|
|
}
|
|
else if (controllerEvents != null)
|
|
{
|
|
GameObject modelController = VRTK_DeviceFinder.GetModelAliasController(controllerEvents.gameObject);
|
|
|
|
if (modelController != null && modelController.activeInHierarchy)
|
|
{
|
|
SDK_BaseController.ControllerHand controllerHand = VRTK_DeviceFinder.GetControllerHand(controllerEvents.gameObject);
|
|
string elementPath = VRTK_SDK_Bridge.GetControllerElementPath(findElement, controllerHand, true);
|
|
returnTransform = (elementPath != null ? modelController.transform.Find(elementPath) : null);
|
|
}
|
|
}
|
|
|
|
return returnTransform;
|
|
}
|
|
}
|
|
}
|