|
|
- // Headset Controller Aware|Presence|70040
- namespace VRTK
- {
- using UnityEngine;
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="raycastHit">The Raycast Hit struct of item that is obscuring the path to the controller.</param>
- /// <param name="controllerReference">The reference to the controller that is being or has been obscured or being or has been glanced.</param>
- public struct HeadsetControllerAwareEventArgs
- {
- public RaycastHit raycastHit;
- public VRTK_ControllerReference controllerReference;
- }
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="sender">this object</param>
- /// <param name="e"><see cref="HeadsetControllerAwareEventArgs"/></param>
- public delegate void HeadsetControllerAwareEventHandler(object sender, HeadsetControllerAwareEventArgs e);
-
- /// <summary>
- /// Determines whether the HMD is in line of sight to the controllers or if the headset is directly looking at one of the controllers.
- /// </summary>
- /// <remarks>
- /// **Script Usage:**
- /// * Place the `VRTK_HeadsetControllerAware` script on any active scene GameObject.
- /// </remarks>
- /// <example>
- /// `VRTK/Examples/029_Controller_Tooltips` displays tooltips that have been added to the controllers and are only visible when the controller is being looked at.
- /// </example>
- [AddComponentMenu("VRTK/Scripts/Presence/VRTK_HeadsetControllerAware")]
- public class VRTK_HeadsetControllerAware : MonoBehaviour
- {
- [Tooltip("If this is checked then the left controller will be checked if items obscure it's path from the headset.")]
- public bool trackLeftController = true;
- [Tooltip("If this is checked then the right controller will be checked if items obscure it's path from the headset.")]
- public bool trackRightController = true;
- [Tooltip("The radius of the accepted distance from the controller origin point to determine if the controller is being looked at.")]
- public float controllerGlanceRadius = 0.15f;
- [Tooltip("A custom transform to provide the world space position of the right controller.")]
- public Transform customRightControllerOrigin;
- [Tooltip("A custom transform to provide the world space position of the left controller.")]
- public Transform customLeftControllerOrigin;
- [Tooltip("A custom raycaster to use when raycasting to find controllers.")]
- public VRTK_CustomRaycast customRaycast;
-
- /// <summary>
- /// Emitted when the controller is obscured by another object.
- /// </summary>
- public event HeadsetControllerAwareEventHandler ControllerObscured;
- /// <summary>
- /// Emitted when the controller is no longer obscured by an object.
- /// </summary>
- public event HeadsetControllerAwareEventHandler ControllerUnobscured;
-
- /// <summary>
- /// Emitted when the controller is seen by the headset view.
- /// </summary>
- public event HeadsetControllerAwareEventHandler ControllerGlanceEnter;
- /// <summary>
- /// Emitted when the controller is no longer seen by the headset view.
- /// </summary>
- public event HeadsetControllerAwareEventHandler ControllerGlanceExit;
-
- protected GameObject leftController;
- protected GameObject rightController;
- protected Transform headset;
-
- protected bool leftControllerObscured = false;
- protected bool rightControllerObscured = false;
- protected bool leftControllerLastState = false;
- protected bool rightControllerLastState = false;
-
- protected bool leftControllerGlance = false;
- protected bool rightControllerGlance = false;
- protected bool leftControllerGlanceLastState = false;
- protected bool rightControllerGlanceLastState = false;
-
- public virtual void OnControllerObscured(HeadsetControllerAwareEventArgs e)
- {
- if (ControllerObscured != null)
- {
- ControllerObscured(this, e);
- }
- }
-
- public virtual void OnControllerUnobscured(HeadsetControllerAwareEventArgs e)
- {
- if (ControllerUnobscured != null)
- {
- ControllerUnobscured(this, e);
- }
- }
-
- public virtual void OnControllerGlanceEnter(HeadsetControllerAwareEventArgs e)
- {
- if (ControllerGlanceEnter != null)
- {
- ControllerGlanceEnter(this, e);
- }
- }
-
- public virtual void OnControllerGlanceExit(HeadsetControllerAwareEventArgs e)
- {
- if (ControllerGlanceExit != null)
- {
- ControllerGlanceExit(this, e);
- }
- }
-
- /// <summary>
- /// The LeftControllerObscured method returns the state of if the left controller is being obscured from the path of the headset.
- /// </summary>
- /// <returns>Returns `true` if the path between the headset and the controller is obscured.</returns>
- public virtual bool LeftControllerObscured()
- {
- return leftControllerObscured;
- }
-
- /// <summary>
- /// The RightControllerObscured method returns the state of if the right controller is being obscured from the path of the headset.
- /// </summary>
- /// <returns>Returns `true` if the path between the headset and the controller is obscured.</returns>
- public virtual bool RightControllerObscured()
- {
- return rightControllerObscured;
- }
-
- /// <summary>
- /// the LeftControllerGlanced method returns the state of if the headset is currently looking at the left controller or not.
- /// </summary>
- /// <returns>Returns `true` if the headset can currently see the controller within the given radius threshold.</returns>
- public virtual bool LeftControllerGlanced()
- {
- return leftControllerGlance;
- }
-
- /// <summary>
- /// the RightControllerGlanced method returns the state of if the headset is currently looking at the right controller or not.
- /// </summary>
- /// <returns>Returns `true` if the headset can currently see the controller within the given radius threshold.</returns>
- public virtual bool RightControllerGlanced()
- {
- return rightControllerGlance;
- }
-
- protected virtual void Awake()
- {
- VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void OnEnable()
- {
- headset = VRTK_DeviceFinder.HeadsetTransform();
- leftController = VRTK_DeviceFinder.GetControllerLeftHand();
- rightController = VRTK_DeviceFinder.GetControllerRightHand();
- }
-
- protected virtual void OnDisable()
- {
- leftController = null;
- rightController = null;
- }
-
- protected virtual void OnDestroy()
- {
- VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void Update()
- {
- if (trackLeftController)
- {
- RayCastToController(leftController, customLeftControllerOrigin, ref leftControllerObscured, ref leftControllerLastState);
- }
- if (trackRightController)
- {
- RayCastToController(rightController, customRightControllerOrigin, ref rightControllerObscured, ref rightControllerLastState);
- }
-
- CheckHeadsetView(leftController, customLeftControllerOrigin, ref leftControllerGlance, ref leftControllerGlanceLastState);
- CheckHeadsetView(rightController, customRightControllerOrigin, ref rightControllerGlance, ref rightControllerGlanceLastState);
- }
-
- protected virtual HeadsetControllerAwareEventArgs SetHeadsetControllerAwareEvent(RaycastHit raycastHit, VRTK_ControllerReference controllerReference)
- {
- HeadsetControllerAwareEventArgs e;
- e.raycastHit = raycastHit;
- e.controllerReference = controllerReference;
- return e;
- }
-
- protected virtual void RayCastToController(GameObject controller, Transform customDestination, ref bool obscured, ref bool lastState)
- {
- obscured = false;
- if (controller != null && controller.gameObject.activeInHierarchy)
- {
- Vector3 destination = (customDestination ? customDestination.position : controller.transform.position);
- RaycastHit hitInfo;
- if (VRTK_CustomRaycast.Linecast(customRaycast, headset.position, destination, out hitInfo, Physics.IgnoreRaycastLayer, QueryTriggerInteraction.Ignore))
- {
- obscured = true;
- }
-
- if (lastState != obscured)
- {
- ObscuredStateChanged(controller.gameObject, obscured, hitInfo);
- }
-
- lastState = obscured;
- }
- }
-
- protected virtual void ObscuredStateChanged(GameObject controller, bool obscured, RaycastHit hitInfo)
- {
- VRTK_ControllerReference controllerReference = VRTK_ControllerReference.GetControllerReference(controller);
- if (obscured)
- {
- OnControllerObscured(SetHeadsetControllerAwareEvent(hitInfo, controllerReference));
- }
- else
- {
- OnControllerUnobscured(SetHeadsetControllerAwareEvent(hitInfo, controllerReference));
- }
- }
-
- protected virtual void CheckHeadsetView(GameObject controller, Transform customDestination, ref bool controllerGlance, ref bool controllerGlanceLastState)
- {
- controllerGlance = false;
- if (controller != null && controller.gameObject.activeInHierarchy)
- {
- Vector3 controllerPosition = (customDestination ? customDestination.position : controller.transform.position);
- float distanceFromHeadsetToController = Vector3.Distance(headset.position, controllerPosition);
- Vector3 lookPoint = headset.position + (headset.forward * distanceFromHeadsetToController);
-
- if (Vector3.Distance(controllerPosition, lookPoint) <= controllerGlanceRadius)
- {
- controllerGlance = true;
- }
-
- if (controllerGlanceLastState != controllerGlance)
- {
- GlanceStateChanged(controller.gameObject, controllerGlance);
- }
-
- controllerGlanceLastState = controllerGlance;
- }
- }
-
- protected virtual void GlanceStateChanged(GameObject controller, bool glance)
- {
- RaycastHit emptyHit = new RaycastHit();
- VRTK_ControllerReference controllerReference = VRTK_ControllerReference.GetControllerReference(controller);
- if (glance)
- {
- OnControllerGlanceEnter(SetHeadsetControllerAwareEvent(emptyHit, controllerReference));
- }
- else
- {
- OnControllerGlanceExit(SetHeadsetControllerAwareEvent(emptyHit, controllerReference));
- }
- }
- }
- }
|