123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- //======= Copyright (c) Valve Corporation, All rights reserved. ===============
- //
- // Purpose: Player interface used to query HMD transforms and VR hands
- //
- //=============================================================================
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- namespace Valve.VR.InteractionSystem
- {
- //-------------------------------------------------------------------------
- // Singleton representing the local VR player/user, with methods for getting
- // the player's hands, head, tracking origin, and guesses for various properties.
- //-------------------------------------------------------------------------
- public class Player : MonoBehaviour
- {
- [Tooltip( "Virtual transform corresponding to the meatspace tracking origin. Devices are tracked relative to this." )]
- public Transform trackingOriginTransform;
- [Tooltip( "List of possible transforms for the head/HMD, including the no-SteamVR fallback camera." )]
- public Transform[] hmdTransforms;
- [Tooltip( "List of possible Hands, including no-SteamVR fallback Hands." )]
- public Hand[] hands;
- [Tooltip( "Reference to the physics collider that follows the player's HMD position." )]
- public Collider headCollider;
- [Tooltip( "These objects are enabled when SteamVR is available" )]
- public GameObject rigSteamVR;
- [Tooltip( "These objects are enabled when SteamVR is not available, or when the user toggles out of VR" )]
- public GameObject rig2DFallback;
- [Tooltip( "The audio listener for this player" )]
- public Transform audioListener;
- [Tooltip("This action lets you know when the player has placed the headset on their head")]
- public SteamVR_Action_Boolean headsetOnHead = SteamVR_Input.GetBooleanAction("HeadsetOnHead");
- public bool allowToggleTo2D = true;
- //-------------------------------------------------
- // Singleton instance of the Player. Only one can exist at a time.
- //-------------------------------------------------
- private static Player _instance;
- public static Player instance
- {
- get
- {
- if ( _instance == null )
- {
- _instance = FindObjectOfType<Player>();
- }
- return _instance;
- }
- }
- //-------------------------------------------------
- // Get the number of active Hands.
- //-------------------------------------------------
- public int handCount
- {
- get
- {
- int count = 0;
- for ( int i = 0; i < hands.Length; i++ )
- {
- if ( hands[i].gameObject.activeInHierarchy )
- {
- count++;
- }
- }
- return count;
- }
- }
- //-------------------------------------------------
- // Get the i-th active Hand.
- //
- // i - Zero-based index of the active Hand to get
- //-------------------------------------------------
- public Hand GetHand( int i )
- {
- for ( int j = 0; j < hands.Length; j++ )
- {
- if ( !hands[j].gameObject.activeInHierarchy )
- {
- continue;
- }
- if ( i > 0 )
- {
- i--;
- continue;
- }
- return hands[j];
- }
- return null;
- }
- //-------------------------------------------------
- public Hand leftHand
- {
- get
- {
- for ( int j = 0; j < hands.Length; j++ )
- {
- if ( !hands[j].gameObject.activeInHierarchy )
- {
- continue;
- }
- if ( hands[j].handType != SteamVR_Input_Sources.LeftHand)
- {
- continue;
- }
- return hands[j];
- }
- return null;
- }
- }
- //-------------------------------------------------
- public Hand rightHand
- {
- get
- {
- for ( int j = 0; j < hands.Length; j++ )
- {
- if ( !hands[j].gameObject.activeInHierarchy )
- {
- continue;
- }
- if ( hands[j].handType != SteamVR_Input_Sources.RightHand)
- {
- continue;
- }
- return hands[j];
- }
- return null;
- }
- }
- //-------------------------------------------------
- // Get Player scale. Assumes it is scaled equally on all axes.
- //-------------------------------------------------
- public float scale
- {
- get
- {
- return transform.lossyScale.x;
- }
- }
- //-------------------------------------------------
- // Get the HMD transform. This might return the fallback camera transform if SteamVR is unavailable or disabled.
- //-------------------------------------------------
- public Transform hmdTransform
- {
- get
- {
- if (hmdTransforms != null)
- {
- for (int i = 0; i < hmdTransforms.Length; i++)
- {
- if (hmdTransforms[i].gameObject.activeInHierarchy)
- return hmdTransforms[i];
- }
- }
- return null;
- }
- }
- //-------------------------------------------------
- // Height of the eyes above the ground - useful for estimating player height.
- //-------------------------------------------------
- public float eyeHeight
- {
- get
- {
- Transform hmd = hmdTransform;
- if ( hmd )
- {
- Vector3 eyeOffset = Vector3.Project( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up );
- return eyeOffset.magnitude / trackingOriginTransform.lossyScale.x;
- }
- return 0.0f;
- }
- }
- //-------------------------------------------------
- // Guess for the world-space position of the player's feet, directly beneath the HMD.
- //-------------------------------------------------
- public Vector3 feetPositionGuess
- {
- get
- {
- Transform hmd = hmdTransform;
- if ( hmd )
- {
- return trackingOriginTransform.position + Vector3.ProjectOnPlane( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up );
- }
- return trackingOriginTransform.position;
- }
- }
- //-------------------------------------------------
- // Guess for the world-space direction of the player's hips/torso. This is effectively just the gaze direction projected onto the floor plane.
- //-------------------------------------------------
- public Vector3 bodyDirectionGuess
- {
- get
- {
- Transform hmd = hmdTransform;
- if ( hmd )
- {
- Vector3 direction = Vector3.ProjectOnPlane( hmd.forward, trackingOriginTransform.up );
- if ( Vector3.Dot( hmd.up, trackingOriginTransform.up ) < 0.0f )
- {
- // The HMD is upside-down. Either
- // -The player is bending over backwards
- // -The player is bent over looking through their legs
- direction = -direction;
- }
- return direction;
- }
- return trackingOriginTransform.forward;
- }
- }
- //-------------------------------------------------
- private void Awake()
- {
- if ( trackingOriginTransform == null )
- {
- trackingOriginTransform = this.transform;
- }
- #if OPENVR_XR_API && UNITY_LEGACY_INPUT_HELPERS
- if (hmdTransforms != null)
- {
- foreach (var hmd in hmdTransforms)
- {
- if (hmd.GetComponent<UnityEngine.SpatialTracking.TrackedPoseDriver>() == null)
- hmd.gameObject.AddComponent<UnityEngine.SpatialTracking.TrackedPoseDriver>();
- }
- }
- #endif
- }
- //-------------------------------------------------
- private IEnumerator Start()
- {
- _instance = this;
- while (SteamVR.initializedState == SteamVR.InitializedStates.None || SteamVR.initializedState == SteamVR.InitializedStates.Initializing)
- yield return null;
- if ( SteamVR.instance != null )
- {
- ActivateRig( rigSteamVR );
- }
- else
- {
- #if !HIDE_DEBUG_UI
- ActivateRig( rig2DFallback );
- #endif
- }
- }
- protected virtual void Update()
- {
- if (SteamVR.initializedState != SteamVR.InitializedStates.InitializeSuccess)
- return;
- if (headsetOnHead != null)
- {
- if (headsetOnHead.GetStateDown(SteamVR_Input_Sources.Head))
- {
- Debug.Log("<b>SteamVR Interaction System</b> Headset placed on head");
- }
- else if (headsetOnHead.GetStateUp(SteamVR_Input_Sources.Head))
- {
- Debug.Log("<b>SteamVR Interaction System</b> Headset removed");
- }
- }
- }
- //-------------------------------------------------
- void OnDrawGizmos()
- {
- if ( this != instance )
- {
- return;
- }
- //NOTE: These gizmo icons don't work in the plugin since the icons need to exist in a specific "Gizmos"
- // folder in your Asset tree. These icons are included under Core/Icons. Moving them into a
- // "Gizmos" folder should make them work again.
- Gizmos.color = Color.white;
- Gizmos.DrawIcon( feetPositionGuess, "vr_interaction_system_feet.png" );
- Gizmos.color = Color.cyan;
- Gizmos.DrawLine( feetPositionGuess, feetPositionGuess + trackingOriginTransform.up * eyeHeight );
- // Body direction arrow
- Gizmos.color = Color.blue;
- Vector3 bodyDirection = bodyDirectionGuess;
- Vector3 bodyDirectionTangent = Vector3.Cross( trackingOriginTransform.up, bodyDirection );
- Vector3 startForward = feetPositionGuess + trackingOriginTransform.up * eyeHeight * 0.75f;
- Vector3 endForward = startForward + bodyDirection * 0.33f;
- Gizmos.DrawLine( startForward, endForward );
- Gizmos.DrawLine( endForward, endForward - 0.033f * ( bodyDirection + bodyDirectionTangent ) );
- Gizmos.DrawLine( endForward, endForward - 0.033f * ( bodyDirection - bodyDirectionTangent ) );
- Gizmos.color = Color.red;
- int count = handCount;
- for ( int i = 0; i < count; i++ )
- {
- Hand hand = GetHand( i );
- if ( hand.handType == SteamVR_Input_Sources.LeftHand)
- {
- Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_left_hand.png" );
- }
- else if ( hand.handType == SteamVR_Input_Sources.RightHand)
- {
- Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_right_hand.png" );
- }
- else
- {
- /*
- Hand.HandType guessHandType = hand.currentHandType;
- if ( guessHandType == Hand.HandType.Left )
- {
- Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_left_hand_question.png" );
- }
- else if ( guessHandType == Hand.HandType.Right )
- {
- Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_right_hand_question.png" );
- }
- else
- {
- Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_unknown_hand.png" );
- }
- */
- }
- }
- }
- //-------------------------------------------------
- public void Draw2DDebug()
- {
- if ( !allowToggleTo2D )
- return;
- if ( !SteamVR.active )
- return;
- int width = 100;
- int height = 25;
- int left = Screen.width / 2 - width / 2;
- int top = Screen.height - height - 10;
- string text = ( rigSteamVR.activeSelf ) ? "2D Debug" : "VR";
- if ( GUI.Button( new Rect( left, top, width, height ), text ) )
- {
- if ( rigSteamVR.activeSelf )
- {
- ActivateRig( rig2DFallback );
- }
- else
- {
- ActivateRig( rigSteamVR );
- }
- }
- }
- //-------------------------------------------------
- private void ActivateRig( GameObject rig )
- {
- rigSteamVR.SetActive( rig == rigSteamVR );
- rig2DFallback.SetActive( rig == rig2DFallback );
- if ( audioListener )
- {
- audioListener.transform.parent = hmdTransform;
- audioListener.transform.localPosition = Vector3.zero;
- audioListener.transform.localRotation = Quaternion.identity;
- }
- }
- //-------------------------------------------------
- public void PlayerShotSelf()
- {
- //Do something appropriate here
- }
- }
- }
|