|
|
- // Headset Collision|Presence|70010
- namespace VRTK
- {
- using UnityEngine;
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="collider">The Collider of the game object the headset has collided with.</param>
- /// <param name="currentTransform">The current Transform of the object that the Headset Collision Fade script is attached to (Camera).</param>
- public struct HeadsetCollisionEventArgs
- {
- public Collider collider;
- public Transform currentTransform;
- }
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="sender">this object</param>
- /// <param name="e"><see cref="HeadsetCollisionEventArgs"/></param>
- public delegate void HeadsetCollisionEventHandler(object sender, HeadsetCollisionEventArgs e);
-
- /// <summary>
- /// Denotes when the HMD is colliding with valid geometry.
- /// </summary>
- /// <remarks>
- /// **Script Usage:**
- /// * Place the `VRTK_HeadsetCollision` script on any active scene GameObject.
- /// </remarks>
- /// <example>
- /// `VRTK/Examples/011_Camera_HeadSetCollisionFading` has collidable walls around the play area and if the user puts their head into any of the walls then the headset will fade to black.
- /// </example>
- [AddComponentMenu("VRTK/Scripts/Presence/VRTK_HeadsetCollision")]
- public class VRTK_HeadsetCollision : MonoBehaviour
- {
- [Tooltip("If this is checked then the headset collision will ignore colliders set to `Is Trigger = true`.")]
- public bool ignoreTriggerColliders = false;
- [Tooltip("The radius of the auto generated sphere collider for detecting collisions on the headset.")]
- public float colliderRadius = 0.1f;
- [Tooltip("A specified VRTK_PolicyList to use to determine whether any objects will be acted upon by the Headset Collision.")]
- public VRTK_PolicyList targetListPolicy;
-
- /// <summary>
- /// Emitted when the user's headset collides with another game object.
- /// </summary>
- public event HeadsetCollisionEventHandler HeadsetCollisionDetect;
- /// <summary>
- /// Emitted when the user's headset stops colliding with a game object.
- /// </summary>
- public event HeadsetCollisionEventHandler HeadsetCollisionEnded;
-
- /// <summary>
- /// Determines if the headset is currently colliding with another object.
- /// </summary>
- [HideInInspector]
- public bool headsetColliding = false;
- /// <summary>
- /// Stores the collider of what the headset is colliding with.
- /// </summary>
- [HideInInspector]
- public Collider collidingWith = null;
-
- protected Transform headset;
- protected VRTK_HeadsetCollider headsetColliderScript;
- protected GameObject headsetColliderContainer;
- protected bool generateCollider = false;
- protected bool generateRigidbody = false;
-
- public virtual void OnHeadsetCollisionDetect(HeadsetCollisionEventArgs e)
- {
- if (HeadsetCollisionDetect != null)
- {
- HeadsetCollisionDetect(this, e);
- }
- }
-
- public virtual void OnHeadsetCollisionEnded(HeadsetCollisionEventArgs e)
- {
- if (HeadsetCollisionEnded != null)
- {
- HeadsetCollisionEnded(this, e);
- }
- }
-
- /// <summary>
- /// The IsColliding method is used to determine if the headset is currently colliding with a valid game object and returns true if it is and false if it is not colliding with anything or an invalid game object.
- /// </summary>
- /// <returns>Returns `true` if the headset is currently colliding with a valid game object.</returns>
- public virtual bool IsColliding()
- {
- return headsetColliding;
- }
-
- /// <summary>
- /// The GetHeadsetColliderContainer method returns the auto generated GameObject that contains the headset collider.
- /// </summary>
- /// <returns>The auto generated headset collider GameObject.</returns>
- public virtual GameObject GetHeadsetColliderContainer()
- {
- return headsetColliderContainer;
- }
-
- protected virtual void Awake()
- {
- VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void OnEnable()
- {
- headset = VRTK_DeviceFinder.HeadsetTransform();
- if (headset != null)
- {
- headsetColliding = false;
- SetupHeadset();
- VRTK_PlayerObject.SetPlayerObject(headsetColliderContainer.gameObject, VRTK_PlayerObject.ObjectTypes.Headset);
- }
- }
-
- protected virtual void OnDisable()
- {
- if (headset != null && headsetColliderScript != null)
- {
- headsetColliderScript.EndCollision(collidingWith);
- TearDownHeadset();
- }
- }
-
- protected virtual void OnDestroy()
- {
- VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void Update()
- {
- if (headsetColliderContainer != null && headsetColliderContainer.transform.parent != headset)
- {
- headsetColliderContainer.transform.SetParent(headset);
- headsetColliderContainer.transform.localPosition = Vector3.zero;
- headsetColliderContainer.transform.localRotation = headset.localRotation;
- }
- }
-
- protected virtual void CreateHeadsetColliderContainer()
- {
- if (headsetColliderContainer == null)
- {
- headsetColliderContainer = new GameObject(VRTK_SharedMethods.GenerateVRTKObjectName(true, "HeadsetColliderContainer"));
- headsetColliderContainer.transform.position = Vector3.zero;
- headsetColliderContainer.transform.localRotation = headset.localRotation;
- headsetColliderContainer.transform.localScale = Vector3.one;
- headsetColliderContainer.layer = LayerMask.NameToLayer("Ignore Raycast");
- }
- }
-
- protected virtual void SetupHeadset()
- {
- Rigidbody headsetRigidbody = headset.GetComponentInChildren<Rigidbody>();
- if (headsetRigidbody == null)
- {
- CreateHeadsetColliderContainer();
- headsetRigidbody = headsetColliderContainer.AddComponent<Rigidbody>();
- headsetRigidbody.constraints = RigidbodyConstraints.FreezeAll;
- generateRigidbody = true;
- }
- headsetRigidbody.isKinematic = true;
- headsetRigidbody.useGravity = false;
-
- Collider headsetCollider = headset.GetComponentInChildren<Collider>();
- if (headsetCollider == null)
- {
- CreateHeadsetColliderContainer();
- SphereCollider newCollider = headsetColliderContainer.gameObject.AddComponent<SphereCollider>();
- newCollider.radius = colliderRadius;
- headsetCollider = newCollider;
- generateCollider = true;
- }
- headsetCollider.isTrigger = true;
-
- if (headsetColliderScript == null)
- {
- GameObject attachTo = (headsetColliderContainer ? headsetColliderContainer : headset.gameObject);
- headsetColliderScript = attachTo.AddComponent<VRTK_HeadsetCollider>();
- headsetColliderScript.SetParent(gameObject);
- headsetColliderScript.SetIgnoreTarget(targetListPolicy);
- }
- }
-
- protected virtual void TearDownHeadset()
- {
- if (generateCollider)
- {
- Destroy(headset.gameObject.GetComponent<BoxCollider>());
- }
- if (generateRigidbody)
- {
- Destroy(headset.gameObject.GetComponent<Rigidbody>());
- }
- if (headsetColliderScript != null)
- {
- Destroy(headsetColliderScript);
- }
- if (headsetColliderContainer != null)
- {
- Destroy(headsetColliderContainer);
- }
- }
- }
-
- public class VRTK_HeadsetCollider : MonoBehaviour
- {
- protected VRTK_HeadsetCollision parent;
- protected VRTK_PolicyList targetListPolicy;
-
- public virtual void SetParent(GameObject setParent)
- {
- parent = setParent.GetComponent<VRTK_HeadsetCollision>();
- }
-
- public virtual void SetIgnoreTarget(VRTK_PolicyList list = null)
- {
- targetListPolicy = list;
- }
-
- public virtual void EndCollision(Collider collider)
- {
- if (collider == null || !VRTK_PlayerObject.IsPlayerObject(collider.gameObject))
- {
- parent.headsetColliding = false;
- parent.collidingWith = null;
- parent.OnHeadsetCollisionEnded(SetHeadsetCollisionEvent(collider, transform));
- }
- }
-
- protected virtual void OnTriggerStay(Collider collider)
- {
- if (parent.ignoreTriggerColliders && collider != null && collider.isTrigger)
- {
- return;
- }
-
- if (enabled && !VRTK_PlayerObject.IsPlayerObject(collider.gameObject) && ValidTarget(collider.transform))
- {
- parent.headsetColliding = true;
- parent.collidingWith = collider;
- parent.OnHeadsetCollisionDetect(SetHeadsetCollisionEvent(collider, transform));
- }
- }
-
- protected virtual void OnTriggerExit(Collider collider)
- {
- if (parent.ignoreTriggerColliders && collider != null && collider.isTrigger)
- {
- return;
- }
-
- EndCollision(collider);
- }
-
- protected virtual void Update()
- {
- if (parent.headsetColliding && (parent.collidingWith == null || !parent.collidingWith.gameObject.activeInHierarchy))
- {
- EndCollision(parent.collidingWith);
- }
- }
-
- protected virtual HeadsetCollisionEventArgs SetHeadsetCollisionEvent(Collider collider, Transform currentTransform)
- {
- HeadsetCollisionEventArgs e;
- e.collider = collider;
- e.currentTransform = currentTransform;
- return e;
- }
-
- protected virtual bool ValidTarget(Transform target)
- {
- return (target != null && !(VRTK_PolicyList.Check(target.gameObject, targetListPolicy)));
- }
- }
- }
|