123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- // 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));
- }
- }
- }
- }
|