Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 30.49 KB | None | 0 0
  1. //======= Copyright (c) Valve Corporation, All rights reserved. ===============
  2. //
  3. // Purpose: The hands used by the player in the vr interaction system
  4. //
  5. //=============================================================================
  6.  
  7. using UnityEngine;
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12.  
  13. namespace Valve.VR.InteractionSystem
  14. {
  15.     //-------------------------------------------------------------------------
  16.     // Links with an appropriate SteamVR controller and facilitates
  17.     // interactions with objects in the virtual world.
  18.     //-------------------------------------------------------------------------
  19.     public class Hand : MonoBehaviour
  20.     {
  21.         public enum HandType
  22.         {
  23.             Left,
  24.             Right,
  25.             Any
  26.         };
  27.  
  28.         // The flags used to determine how an object is attached to the hand.
  29.         [Flags]
  30.         public enum AttachmentFlags
  31.         {
  32.             SnapOnAttach = 1 << 0, // The object should snap to the position of the specified attachment point on the hand.
  33.             DetachOthers = 1 << 1, // Other objects attached to this hand will be detached.
  34.             DetachFromOtherHand = 1 << 2, // This object will be detached from the other hand.
  35.             ParentToHand = 1 << 3, // The object will be parented to the hand.
  36.         };
  37.  
  38.         public const AttachmentFlags defaultAttachmentFlags = AttachmentFlags.ParentToHand |
  39.                                                               AttachmentFlags.DetachOthers |
  40.                                                               AttachmentFlags.DetachFromOtherHand |
  41.                                                               AttachmentFlags.SnapOnAttach;
  42.  
  43.         public Hand otherHand;
  44.         public HandType startingHandType;
  45.  
  46.         public Transform hoverSphereTransform;
  47.         public float hoverSphereRadius = 0.05f;
  48.         public LayerMask hoverLayerMask = -1;
  49.         public float hoverUpdateInterval = 0.1f;
  50.  
  51.         public Camera noSteamVRFallbackCamera;
  52.         public float noSteamVRFallbackMaxDistanceNoItem = 10.0f;
  53.         public float noSteamVRFallbackMaxDistanceWithItem = 0.5f;
  54.         private float noSteamVRFallbackInteractorDistance = -1.0f;
  55.  
  56.         public SteamVR_Controller.Device controller;
  57.  
  58.         public GameObject controllerPrefab;
  59.         private GameObject controllerObject = null;
  60.  
  61.         public bool showDebugText = false;
  62.         public bool spewDebugText = false;
  63.  
  64.         public struct AttachedObject
  65.         {
  66.             public GameObject attachedObject;
  67.             public GameObject originalParent;
  68.             public bool isParentedToHand;
  69.         }
  70.  
  71.         private List<AttachedObject> attachedObjects = new List<AttachedObject>();
  72.  
  73.         public ReadOnlyCollection<AttachedObject> AttachedObjects
  74.         {
  75.             get { return attachedObjects.AsReadOnly(); }
  76.         }
  77.  
  78.         public bool hoverLocked { get; private set; }
  79.  
  80.         private Interactable _hoveringInteractable;
  81.  
  82.         private TextMesh debugText;
  83.         private int prevOverlappingColliders = 0;
  84.  
  85.         private const int ColliderArraySize = 16;
  86.         private Collider[] overlappingColliders;
  87.  
  88.         private Player playerInstance;
  89.  
  90.         private GameObject applicationLostFocusObject;
  91.  
  92.         SteamVR_Events.Action inputFocusAction;
  93.  
  94.         private SteamVR_Controller.Device c { get { return SteamVR_Controller.Input((int)ControllerTracked.index); } } // games we played wuz here
  95.         [HideInInspector]
  96.         public Valve.VR.EVRButtonId trigger = Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger; // Trigger
  97.         [HideInInspector]
  98.         private Valve.VR.EVRButtonId grip = Valve.VR.EVRButtonId.k_EButton_Grip; // Grip
  99.         private SteamVR_TrackedObject ControllerTracked;
  100.  
  101.         //-------------------------------------------------
  102.         // The Interactable object this Hand is currently hovering over
  103.         //-------------------------------------------------
  104.         public Interactable hoveringInteractable
  105.         {
  106.             get { return _hoveringInteractable; }
  107.             set
  108.             {
  109.                 if ( _hoveringInteractable != value )
  110.                 {
  111.                     if ( _hoveringInteractable != null )
  112.                     {
  113.                         HandDebugLog( "HoverEnd " + _hoveringInteractable.gameObject );
  114.                         _hoveringInteractable.SendMessage( "OnHandHoverEnd", this, SendMessageOptions.DontRequireReceiver );
  115.  
  116.                         //Note: The _hoveringInteractable can change after sending the OnHandHoverEnd message so we need to check it again before broadcasting this message
  117.                         if ( _hoveringInteractable != null )
  118.                         {
  119.                             this.BroadcastMessage( "OnParentHandHoverEnd", _hoveringInteractable, SendMessageOptions.DontRequireReceiver ); // let objects attached to the hand know that a hover has ended
  120.                         }
  121.                     }
  122.  
  123.                     _hoveringInteractable = value;
  124.  
  125.                     if ( _hoveringInteractable != null )
  126.                     {
  127.                         HandDebugLog( "HoverBegin " + _hoveringInteractable.gameObject );
  128.                         _hoveringInteractable.SendMessage( "OnHandHoverBegin", this, SendMessageOptions.DontRequireReceiver );
  129.  
  130.                         //Note: The _hoveringInteractable can change after sending the OnHandHoverBegin message so we need to check it again before broadcasting this message
  131.                         if ( _hoveringInteractable != null )
  132.                         {
  133.                             this.BroadcastMessage( "OnParentHandHoverBegin", _hoveringInteractable, SendMessageOptions.DontRequireReceiver ); // let objects attached to the hand know that a hover has begun
  134.                         }
  135.                     }
  136.                 }
  137.             }
  138.         }
  139.  
  140.  
  141.         //-------------------------------------------------
  142.         // Active GameObject attached to this Hand
  143.         //-------------------------------------------------
  144.         public GameObject currentAttachedObject
  145.         {
  146.             get
  147.             {
  148.                 CleanUpAttachedObjectStack();
  149.  
  150.                 if ( attachedObjects.Count > 0 )
  151.                 {
  152.                     return attachedObjects[attachedObjects.Count - 1].attachedObject;
  153.                 }
  154.  
  155.                 return null;
  156.             }
  157.         }
  158.  
  159.  
  160.         //-------------------------------------------------
  161.         public Transform GetAttachmentTransform( string attachmentPoint = "" )
  162.         {
  163.             Transform attachmentTransform = null;
  164.  
  165.             if ( !string.IsNullOrEmpty( attachmentPoint ) )
  166.             {
  167.                 attachmentTransform = transform.Find( attachmentPoint );
  168.             }
  169.  
  170.             if ( !attachmentTransform )
  171.             {
  172.                 attachmentTransform = this.transform;
  173.             }
  174.  
  175.             return attachmentTransform;
  176.         }
  177.  
  178.  
  179.         //-------------------------------------------------
  180.         // Guess the type of this Hand
  181.         //
  182.         // If startingHandType is Hand.Left or Hand.Right, returns startingHandType.
  183.         // If otherHand is non-null and both Hands are linked to controllers, returns
  184.         // Hand.Left if this Hand is leftmost relative to the HMD, otherwise Hand.Right.
  185.         // Otherwise, returns Hand.Any
  186.         //-------------------------------------------------
  187.         public HandType GuessCurrentHandType()
  188.         {
  189.             if ( startingHandType == HandType.Left || startingHandType == HandType.Right )
  190.             {
  191.                 return startingHandType;
  192.             }
  193.  
  194.             if ( startingHandType == HandType.Any && otherHand != null && otherHand.controller == null )
  195.             {
  196.                 return HandType.Right;
  197.             }
  198.  
  199.             if ( controller == null || otherHand == null || otherHand.controller == null )
  200.             {
  201.                 return startingHandType;
  202.             }
  203.  
  204.             if ( controller.index == SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Leftmost ) )
  205.             {
  206.                 return HandType.Left;
  207.             }
  208.  
  209.             return HandType.Right;
  210.         }
  211.  
  212.  
  213.         //-------------------------------------------------
  214.         // Attach a GameObject to this GameObject
  215.         //
  216.         // objectToAttach - The GameObject to attach
  217.         // flags - The flags to use for attaching the object
  218.         // attachmentPoint - Name of the GameObject in the hierarchy of this Hand which should act as the attachment point for this GameObject
  219.         //-------------------------------------------------
  220.         public void AttachObject( GameObject objectToAttach, AttachmentFlags flags = defaultAttachmentFlags, string attachmentPoint = "" )
  221.         {
  222.             if ( flags == 0 )
  223.             {
  224.                 flags = defaultAttachmentFlags;
  225.             }
  226.  
  227.             //Make sure top object on stack is non-null
  228.             CleanUpAttachedObjectStack();
  229.  
  230.             //Detach the object if it is already attached so that it can get re-attached at the top of the stack
  231.             DetachObject( objectToAttach );
  232.  
  233.             //Detach from the other hand if requested
  234.             if ( ( ( flags & AttachmentFlags.DetachFromOtherHand ) == AttachmentFlags.DetachFromOtherHand ) && otherHand )
  235.             {
  236.                 otherHand.DetachObject( objectToAttach );
  237.             }
  238.  
  239.             if ( ( flags & AttachmentFlags.DetachOthers ) == AttachmentFlags.DetachOthers )
  240.             {
  241.                 //Detach all the objects from the stack
  242.                 while ( attachedObjects.Count > 0 )
  243.                 {
  244.                     DetachObject( attachedObjects[0].attachedObject );
  245.                 }
  246.             }
  247.  
  248.             if ( currentAttachedObject )
  249.             {
  250.                 currentAttachedObject.SendMessage( "OnHandFocusLost", this, SendMessageOptions.DontRequireReceiver );
  251.             }
  252.  
  253.             AttachedObject attachedObject = new AttachedObject();
  254.             attachedObject.attachedObject = objectToAttach;
  255.             attachedObject.originalParent = objectToAttach.transform.parent != null ? objectToAttach.transform.parent.gameObject : null;
  256.             if ( ( flags & AttachmentFlags.ParentToHand ) == AttachmentFlags.ParentToHand )
  257.             {
  258.                 //Parent the object to the hand
  259.                 objectToAttach.transform.parent = GetAttachmentTransform( attachmentPoint );
  260.                 attachedObject.isParentedToHand = true;
  261.             }
  262.             else
  263.             {
  264.                 attachedObject.isParentedToHand = false;
  265.             }
  266.             attachedObjects.Add( attachedObject );
  267.  
  268.             if ( ( flags & AttachmentFlags.SnapOnAttach ) == AttachmentFlags.SnapOnAttach )
  269.             {
  270.                 objectToAttach.transform.localPosition = Vector3.zero;
  271.                 objectToAttach.transform.localRotation = Quaternion.identity;
  272.             }
  273.  
  274.             HandDebugLog( "AttachObject " + objectToAttach );
  275.             objectToAttach.SendMessage( "OnAttachedToHand", this, SendMessageOptions.DontRequireReceiver );
  276.  
  277.             UpdateHovering();
  278.         }
  279.  
  280.  
  281.         //-------------------------------------------------
  282.         // Detach this GameObject from the attached object stack of this Hand
  283.         //
  284.         // objectToDetach - The GameObject to detach from this Hand
  285.         //-------------------------------------------------
  286.         public void DetachObject( GameObject objectToDetach, bool restoreOriginalParent = true )
  287.         {
  288.             int index = attachedObjects.FindIndex( l => l.attachedObject == objectToDetach );
  289.             if ( index != -1 )
  290.             {
  291.                 HandDebugLog( "DetachObject " + objectToDetach );
  292.  
  293.                 GameObject prevTopObject = currentAttachedObject;
  294.  
  295.                 Transform parentTransform = null;
  296.                 if ( attachedObjects[index].isParentedToHand )
  297.                 {
  298.                     if ( restoreOriginalParent && ( attachedObjects[index].originalParent != null ) )
  299.                     {
  300.                         parentTransform = attachedObjects[index].originalParent.transform;
  301.                     }
  302.                     attachedObjects[index].attachedObject.transform.parent = parentTransform;
  303.                 }
  304.  
  305.                 attachedObjects[index].attachedObject.SetActive( true );
  306.                 attachedObjects[index].attachedObject.SendMessage( "OnDetachedFromHand", this, SendMessageOptions.DontRequireReceiver );
  307.                 attachedObjects.RemoveAt( index );
  308.  
  309.                 GameObject newTopObject = currentAttachedObject;
  310.  
  311.                 //Give focus to the top most object on the stack if it changed
  312.                 if ( newTopObject != null && newTopObject != prevTopObject )
  313.                 {
  314.                     newTopObject.SetActive( true );
  315.                     newTopObject.SendMessage( "OnHandFocusAcquired", this, SendMessageOptions.DontRequireReceiver );
  316.                 }
  317.             }
  318.  
  319.             CleanUpAttachedObjectStack();
  320.         }
  321.  
  322.  
  323.         //-------------------------------------------------
  324.         // Get the world velocity of the VR Hand.
  325.         // Note: controller velocity value only updates on controller events (Button but and down) so good for throwing
  326.         //-------------------------------------------------
  327.         public Vector3 GetTrackedObjectVelocity()
  328.         {
  329.             if ( controller != null )
  330.             {
  331.                 return transform.parent.TransformVector( controller.velocity );
  332.             }
  333.  
  334.             return Vector3.zero;
  335.         }
  336.  
  337.  
  338.         //-------------------------------------------------
  339.         // Get the world angular velocity of the VR Hand.
  340.         // Note: controller velocity value only updates on controller events (Button but and down) so good for throwing
  341.         //-------------------------------------------------
  342.         public Vector3 GetTrackedObjectAngularVelocity()
  343.         {
  344.             if ( controller != null )
  345.             {
  346.                 return transform.parent.TransformVector( controller.angularVelocity );
  347.             }
  348.  
  349.             return Vector3.zero;
  350.         }
  351.  
  352.  
  353.         //-------------------------------------------------
  354.         private void CleanUpAttachedObjectStack()
  355.         {
  356.             attachedObjects.RemoveAll( l => l.attachedObject == null );
  357.         }
  358.  
  359.  
  360.         //-------------------------------------------------
  361.         void Awake()
  362.         {
  363.             ControllerTracked = GetComponent<SteamVR_TrackedObject>(); //gamesweplayed wuz here
  364.             inputFocusAction = SteamVR_Events.InputFocusAction( OnInputFocus );
  365.  
  366.             if ( hoverSphereTransform == null )
  367.             {
  368.                 hoverSphereTransform = this.transform;
  369.             }
  370.  
  371.             applicationLostFocusObject = new GameObject( "_application_lost_focus" );
  372.             applicationLostFocusObject.transform.parent = transform;
  373.             applicationLostFocusObject.SetActive( false );
  374.         }
  375.  
  376.  
  377.         //-------------------------------------------------
  378.         IEnumerator Start()
  379.         {
  380.             // save off player instance
  381.             playerInstance = Player.instance;
  382.             if ( !playerInstance )
  383.             {
  384.                 Debug.LogError( "No player instance found in Hand Start()" );
  385.             }
  386.  
  387.             // allocate array for colliders
  388.             overlappingColliders = new Collider[ColliderArraySize];
  389.  
  390.             // We are a "no SteamVR fallback hand" if we have this camera set
  391.             // we'll use the right mouse to look around and left mouse to interact
  392.             // - don't need to find the device
  393.             if ( noSteamVRFallbackCamera )
  394.             {
  395.                 yield break;
  396.             }
  397.  
  398.             //Debug.Log( "Hand - initializing connection routine" );
  399.  
  400.             // Acquire the correct device index for the hand we want to be
  401.             // Also for the other hand if we get there first
  402.             while ( true )
  403.             {
  404.                 // Don't need to run this every frame
  405.                 yield return new WaitForSeconds( 1.0f );
  406.  
  407.                 // We have a controller now, break out of the loop!
  408.                 if ( controller != null )
  409.                     break;
  410.  
  411.                 //Debug.Log( "Hand - checking controllers..." );
  412.  
  413.                 // Initialize both hands simultaneously
  414.                 if ( startingHandType == HandType.Left || startingHandType == HandType.Right )
  415.                 {
  416.                     // Left/right relationship.
  417.                     // Wait until we have a clear unique left-right relationship to initialize.
  418.                     int leftIndex = SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Leftmost );
  419.                     int rightIndex = SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Rightmost );
  420.                     if ( leftIndex == -1 || rightIndex == -1 || leftIndex == rightIndex )
  421.                     {
  422.                         //Debug.Log( string.Format( "...Left/right hand relationship not yet established: leftIndex={0}, rightIndex={1}", leftIndex, rightIndex ) );
  423.                         continue;
  424.                     }
  425.  
  426.                     int myIndex = ( startingHandType == HandType.Right ) ? rightIndex : leftIndex;
  427.                     int otherIndex = ( startingHandType == HandType.Right ) ? leftIndex : rightIndex;
  428.  
  429.                     InitController( myIndex );
  430.                     if ( otherHand )
  431.                     {
  432.                         otherHand.InitController( otherIndex );
  433.                     }
  434.                 }
  435.                 else
  436.                 {
  437.                     // No left/right relationship. Just wait for a connection
  438.  
  439.                     var vr = SteamVR.instance;
  440.                     for ( int i = 0; i < Valve.VR.OpenVR.k_unMaxTrackedDeviceCount; i++ )
  441.                     {
  442.                         if ( vr.hmd.GetTrackedDeviceClass( (uint)i ) != Valve.VR.ETrackedDeviceClass.Controller )
  443.                         {
  444.                             //Debug.Log( string.Format( "Hand - device {0} is not a controller", i ) );
  445.                             continue;
  446.                         }
  447.  
  448.                         var device = SteamVR_Controller.Input( i );
  449.                         if ( !device.valid )
  450.                         {
  451.                             //Debug.Log( string.Format( "Hand - device {0} is not valid", i ) );
  452.                             continue;
  453.                         }
  454.  
  455.                         if ( ( otherHand != null ) && ( otherHand.controller != null ) )
  456.                         {
  457.                             // Other hand is using this index, so we cannot use it.
  458.                             if ( i == (int)otherHand.controller.index )
  459.                             {
  460.                                 //Debug.Log( string.Format( "Hand - device {0} is owned by the other hand", i ) );
  461.                                 continue;
  462.                             }
  463.                         }
  464.  
  465.                         InitController( i );
  466.                     }
  467.                 }
  468.             }
  469.         }
  470.  
  471.  
  472.         //-------------------------------------------------
  473.         private void UpdateHovering()
  474.         {
  475.             if ( ( noSteamVRFallbackCamera == null ) && ( controller == null ) )
  476.             {
  477.                 return;
  478.             }
  479.  
  480.             if ( hoverLocked )
  481.                 return;
  482.  
  483.             if ( applicationLostFocusObject.activeSelf )
  484.                 return;
  485.  
  486.             float closestDistance = float.MaxValue;
  487.             Interactable closestInteractable = null;
  488.  
  489.             // Pick the closest hovering
  490.             float flHoverRadiusScale = playerInstance.transform.lossyScale.x;
  491.             float flScaledSphereRadius = hoverSphereRadius * flHoverRadiusScale;
  492.  
  493.             // if we're close to the floor, increase the radius to make things easier to pick up
  494.             float handDiff = Mathf.Abs( transform.position.y - playerInstance.trackingOriginTransform.position.y );
  495.             float boxMult = Util.RemapNumberClamped( handDiff, 0.0f, 0.5f * flHoverRadiusScale, 5.0f, 1.0f ) * flHoverRadiusScale;
  496.  
  497.             // null out old vals
  498.             for ( int i = 0; i < overlappingColliders.Length; ++i )
  499.             {
  500.                 overlappingColliders[i] = null;
  501.             }
  502.  
  503.             Physics.OverlapBoxNonAlloc(
  504.                 hoverSphereTransform.position - new Vector3( 0, flScaledSphereRadius * boxMult - flScaledSphereRadius, 0 ),
  505.                 new Vector3( flScaledSphereRadius, flScaledSphereRadius * boxMult * 2.0f, flScaledSphereRadius ),
  506.                 overlappingColliders,
  507.                 Quaternion.identity,
  508.                 hoverLayerMask.value
  509.             );
  510.  
  511.             // DebugVar
  512.             int iActualColliderCount = 0;
  513.  
  514.             foreach ( Collider collider in overlappingColliders )
  515.             {
  516.                 if ( collider == null )
  517.                     continue;
  518.  
  519.                 Interactable contacting = collider.GetComponentInParent<Interactable>();
  520.  
  521.                 // Yeah, it's null, skip
  522.                 if ( contacting == null )
  523.                     continue;
  524.  
  525.                 // Ignore this collider for hovering
  526.                 IgnoreHovering ignore = collider.GetComponent<IgnoreHovering>();
  527.                 if ( ignore != null )
  528.                 {
  529.                     if ( ignore.onlyIgnoreHand == null || ignore.onlyIgnoreHand == this )
  530.                     {
  531.                         continue;
  532.                     }
  533.                 }
  534.  
  535.                 // Can't hover over the object if it's attached
  536.                 if ( attachedObjects.FindIndex( l => l.attachedObject == contacting.gameObject ) != -1 )
  537.                     continue;
  538.  
  539.                 // Occupied by another hand, so we can't touch it
  540.                 if ( otherHand && otherHand.hoveringInteractable == contacting )
  541.                     continue;
  542.  
  543.                 // Best candidate so far...
  544.                 float distance = Vector3.Distance( contacting.transform.position, hoverSphereTransform.position );
  545.                 if ( distance < closestDistance )
  546.                 {
  547.                     closestDistance = distance;
  548.                     closestInteractable = contacting;
  549.                 }
  550.                 iActualColliderCount++;
  551.             }
  552.  
  553.             // Hover on this one
  554.             hoveringInteractable = closestInteractable;
  555.  
  556.             if ( iActualColliderCount > 0 && iActualColliderCount != prevOverlappingColliders )
  557.             {
  558.                 prevOverlappingColliders = iActualColliderCount;
  559.                 HandDebugLog( "Found " + iActualColliderCount + " overlapping colliders." );
  560.             }
  561.         }
  562.  
  563.  
  564.         //-------------------------------------------------
  565.         private void UpdateNoSteamVRFallback()
  566.         {
  567.             if ( noSteamVRFallbackCamera )
  568.             {
  569.                 Ray ray = noSteamVRFallbackCamera.ScreenPointToRay( Input.mousePosition );
  570.  
  571.                 if ( attachedObjects.Count > 0 )
  572.                 {
  573.                     // Holding down the mouse:
  574.                     // move around a fixed distance from the camera
  575.                     transform.position = ray.origin + noSteamVRFallbackInteractorDistance * ray.direction;
  576.                 }
  577.                 else
  578.                 {
  579.                     // Not holding down the mouse:
  580.                     // cast out a ray to see what we should mouse over
  581.  
  582.                     // Don't want to hit the hand and anything underneath it
  583.                     // So move it back behind the camera when we do the raycast
  584.                     Vector3 oldPosition = transform.position;
  585.                     transform.position = noSteamVRFallbackCamera.transform.forward * ( -1000.0f );
  586.  
  587.                     RaycastHit raycastHit;
  588.                     if ( Physics.Raycast( ray, out raycastHit, noSteamVRFallbackMaxDistanceNoItem ) )
  589.                     {
  590.                         transform.position = raycastHit.point;
  591.  
  592.                         // Remember this distance in case we click and drag the mouse
  593.                         noSteamVRFallbackInteractorDistance = Mathf.Min( noSteamVRFallbackMaxDistanceNoItem, raycastHit.distance );
  594.                     }
  595.                     else if ( noSteamVRFallbackInteractorDistance > 0.0f )
  596.                     {
  597.                         // Move it around at the distance we last had a hit
  598.                         transform.position = ray.origin + Mathf.Min( noSteamVRFallbackMaxDistanceNoItem, noSteamVRFallbackInteractorDistance ) * ray.direction;
  599.                     }
  600.                     else
  601.                     {
  602.                         // Didn't hit, just leave it where it was
  603.                         transform.position = oldPosition;
  604.                     }
  605.                 }
  606.             }
  607.         }
  608.  
  609.  
  610.         //-------------------------------------------------
  611.         private void UpdateDebugText()
  612.         {
  613.             if ( showDebugText )
  614.             {
  615.                 if ( debugText == null )
  616.                 {
  617.                     debugText = new GameObject( "_debug_text" ).AddComponent<TextMesh>();
  618.                     debugText.fontSize = 120;
  619.                     debugText.characterSize = 0.001f;
  620.                     debugText.transform.parent = transform;
  621.  
  622.                     debugText.transform.localRotation = Quaternion.Euler( 90.0f, 0.0f, 0.0f );
  623.                 }
  624.  
  625.                 if ( GuessCurrentHandType() == HandType.Right )
  626.                 {
  627.                     debugText.transform.localPosition = new Vector3( -0.05f, 0.0f, 0.0f );
  628.                     debugText.alignment = TextAlignment.Right;
  629.                     debugText.anchor = TextAnchor.UpperRight;
  630.                 }
  631.                 else
  632.                 {
  633.                     debugText.transform.localPosition = new Vector3( 0.05f, 0.0f, 0.0f );
  634.                     debugText.alignment = TextAlignment.Left;
  635.                     debugText.anchor = TextAnchor.UpperLeft;
  636.                 }
  637.  
  638.                 debugText.text = string.Format(
  639.                     "Hovering: {0}\n" +
  640.                     "Hover Lock: {1}\n" +
  641.                     "Attached: {2}\n" +
  642.                     "Total Attached: {3}\n" +
  643.                     "Type: {4}\n",
  644.                     ( hoveringInteractable ? hoveringInteractable.gameObject.name : "null" ),
  645.                     hoverLocked,
  646.                     ( currentAttachedObject ? currentAttachedObject.name : "null" ),
  647.                     attachedObjects.Count,
  648.                     GuessCurrentHandType().ToString() );
  649.             }
  650.             else
  651.             {
  652.                 if ( debugText != null )
  653.                 {
  654.                     Destroy( debugText.gameObject );
  655.                 }
  656.             }
  657.         }
  658.  
  659.  
  660.         //-------------------------------------------------
  661.         void OnEnable()
  662.         {
  663.             inputFocusAction.enabled = true;
  664.  
  665.             // Stagger updates between hands
  666.             float hoverUpdateBegin = ( ( otherHand != null ) && ( otherHand.GetInstanceID() < GetInstanceID() ) ) ? ( 0.5f * hoverUpdateInterval ) : ( 0.0f );
  667.             InvokeRepeating( "UpdateHovering", hoverUpdateBegin, hoverUpdateInterval );
  668.             InvokeRepeating( "UpdateDebugText", hoverUpdateBegin, hoverUpdateInterval );
  669.         }
  670.  
  671.  
  672.         //-------------------------------------------------
  673.         void OnDisable()
  674.         {
  675.             inputFocusAction.enabled = false;
  676.  
  677.             CancelInvoke();
  678.         }
  679.  
  680.  
  681.         //-------------------------------------------------
  682.         void Update()
  683.         {
  684.             UpdateNoSteamVRFallback();
  685.  
  686.             GameObject attached = currentAttachedObject;
  687.             if ( attached )
  688.             {
  689.                 attached.SendMessage( "HandAttachedUpdate", this, SendMessageOptions.DontRequireReceiver );
  690.             }
  691.  
  692.             if ( hoveringInteractable )
  693.             {
  694.                 hoveringInteractable.SendMessage( "HandHoverUpdate", this, SendMessageOptions.DontRequireReceiver );
  695.             }
  696.         }
  697.  
  698.  
  699.         //-------------------------------------------------
  700.         void LateUpdate()
  701.         {
  702.             //Re-attach the controller if nothing else is attached to the hand
  703.             if ( controllerObject != null && attachedObjects.Count == 0 )
  704.             {
  705.                 AttachObject( controllerObject );
  706.             }
  707.         }
  708.  
  709.  
  710.         //-------------------------------------------------
  711.         private void OnInputFocus( bool hasFocus )
  712.         {
  713.             if ( hasFocus )
  714.             {
  715.                 DetachObject( applicationLostFocusObject, true );
  716.                 applicationLostFocusObject.SetActive( false );
  717.                 UpdateHandPoses();
  718.                 UpdateHovering();
  719.                 BroadcastMessage( "OnParentHandInputFocusAcquired", SendMessageOptions.DontRequireReceiver );
  720.             }
  721.             else
  722.             {
  723.                 applicationLostFocusObject.SetActive( true );
  724.                 AttachObject( applicationLostFocusObject, AttachmentFlags.ParentToHand );
  725.                 BroadcastMessage( "OnParentHandInputFocusLost", SendMessageOptions.DontRequireReceiver );
  726.             }
  727.         }
  728.  
  729.  
  730.         //-------------------------------------------------
  731.         void FixedUpdate()
  732.         {
  733.             UpdateHandPoses();
  734.         }
  735.  
  736.  
  737.         //-------------------------------------------------
  738.         void OnDrawGizmos()
  739.         {
  740.             Gizmos.color = new Color( 0.5f, 1.0f, 0.5f, 0.9f );
  741.             Transform sphereTransform = hoverSphereTransform ? hoverSphereTransform : this.transform;
  742.             Gizmos.DrawWireSphere( sphereTransform.position, hoverSphereRadius );
  743.         }
  744.  
  745.  
  746.         //-------------------------------------------------
  747.         private void HandDebugLog( string msg )
  748.         {
  749.             if ( spewDebugText )
  750.             {
  751.                 Debug.Log( "Hand (" + this.name + "): " + msg );
  752.             }
  753.         }
  754.  
  755.  
  756.         //-------------------------------------------------
  757.         private void UpdateHandPoses()
  758.         {
  759.             if ( controller != null )
  760.             {
  761.                 SteamVR vr = SteamVR.instance;
  762.                 if ( vr != null )
  763.                 {
  764.                     var pose = new Valve.VR.TrackedDevicePose_t();
  765.                     var gamePose = new Valve.VR.TrackedDevicePose_t();
  766.                     var err = vr.compositor.GetLastPoseForTrackedDeviceIndex( controller.index, ref pose, ref gamePose );
  767.                     if ( err == Valve.VR.EVRCompositorError.None )
  768.                     {
  769.                         var t = new SteamVR_Utils.RigidTransform( gamePose.mDeviceToAbsoluteTracking );
  770.                         transform.localPosition = t.pos;
  771.                         transform.localRotation = t.rot;
  772.                     }
  773.                 }
  774.             }
  775.         }
  776.  
  777.  
  778.         //-------------------------------------------------
  779.         // Continue to hover over this object indefinitely, whether or not the Hand moves out of its interaction trigger volume.
  780.         //
  781.         // interactable - The Interactable to hover over indefinitely.
  782.         //-------------------------------------------------
  783.         public void HoverLock( Interactable interactable )
  784.         {
  785.             HandDebugLog( "HoverLock " + interactable );
  786.             hoverLocked = true;
  787.             hoveringInteractable = interactable;
  788.         }
  789.  
  790.  
  791.         //-------------------------------------------------
  792.         // Stop hovering over this object indefinitely.
  793.         //
  794.         // interactable - The hover-locked Interactable to stop hovering over indefinitely.
  795.         //-------------------------------------------------
  796.         public void HoverUnlock( Interactable interactable )
  797.         {
  798.             HandDebugLog( "HoverUnlock " + interactable );
  799.             if ( hoveringInteractable == interactable )
  800.             {
  801.                 hoverLocked = false;
  802.             }
  803.         }
  804.  
  805.         //-------------------------------------------------
  806.         // Was the standard interaction button just pressed? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click.
  807.         //-------------------------------------------------
  808.         public bool GetStandardInteractionButtonDown()
  809.         {
  810.             if ( noSteamVRFallbackCamera )
  811.             {
  812.                 return Input.GetMouseButtonDown( 0 );
  813.             }
  814.             else if ( controller != null )
  815.             {
  816.                 return controller.GetHairTriggerDown();
  817.             }
  818.  
  819.             return false;
  820.         }
  821.  
  822.         public bool GetOculusGripButtonDown() // gamesweplayed wus here
  823.         {
  824.             if (noSteamVRFallbackCamera)
  825.             {
  826.                 return Input.GetMouseButtonDown(0);
  827.             }
  828.             else if (controller != null)
  829.             {
  830.                 return c.GetPressDown(grip);
  831.             }
  832.  
  833.             return false;
  834.         }
  835.         //-------------------------------------------------
  836.         // Was the standard interaction button just released? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click.
  837.         //-------------------------------------------------
  838.         public bool GetStandardInteractionButtonUp()
  839.         {
  840.             if ( noSteamVRFallbackCamera )
  841.             {
  842.                 return Input.GetMouseButtonUp( 0 );
  843.             }
  844.             else if ( controller != null )
  845.             {
  846.                 return controller.GetHairTriggerUp();
  847.             }
  848.  
  849.             return false;
  850.         }
  851.  
  852.         public bool GetOculusGripButtonUp() // gamesweplayed wus here
  853.         {
  854.             if (noSteamVRFallbackCamera)
  855.             {
  856.                 return Input.GetMouseButtonDown(0);
  857.             }
  858.             else if (controller != null)
  859.             {
  860.                 return c.GetPressUp(grip);
  861.             }
  862.  
  863.             return false;
  864.         }
  865.         //-------------------------------------------------
  866.         // Is the standard interaction button being pressed? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click.
  867.         //-------------------------------------------------
  868.         public bool GetStandardInteractionButton()
  869.         {
  870.             if ( noSteamVRFallbackCamera )
  871.             {
  872.                 return Input.GetMouseButton( 0 );
  873.             }
  874.             else if ( controller != null )
  875.             {
  876.                 return controller.GetHairTrigger();
  877.             }
  878.  
  879.             return false;
  880.         }
  881.  
  882.         public bool GetOculusGripButton() // gamesweplayed wus here
  883.         {
  884.             if (noSteamVRFallbackCamera)
  885.             {
  886.                 return Input.GetMouseButtonDown(0);
  887.             }
  888.             else if (controller != null)
  889.             {
  890.                 return c.GetPress(grip);
  891.             }
  892.  
  893.             return false;
  894.         }
  895.         //-------------------------------------------------
  896.         private void InitController( int index )
  897.         {
  898.             if ( controller == null )
  899.             {
  900.                 controller = SteamVR_Controller.Input( index );
  901.  
  902.                 HandDebugLog( "Hand " + name + " connected with device index " + controller.index );
  903.  
  904.                 controllerObject = GameObject.Instantiate( controllerPrefab );
  905.                 controllerObject.SetActive( true );
  906.                 controllerObject.name = controllerPrefab.name + "_" + this.name;
  907.                 AttachObject( controllerObject );
  908.                 controller.TriggerHapticPulse( 800 );
  909.  
  910.                 // If the player's scale has been changed the object to attach will be the wrong size.
  911.                 // To fix this we change the object's scale back to its original, pre-attach scale.
  912.                 controllerObject.transform.localScale = controllerPrefab.transform.localScale;
  913.  
  914.                 this.BroadcastMessage( "OnHandInitialized", index, SendMessageOptions.DontRequireReceiver ); // let child objects know we've initialized
  915.             }
  916.         }
  917.     }
  918.  
  919. #if UNITY_EDITOR
  920.     //-------------------------------------------------------------------------
  921.     [UnityEditor.CustomEditor( typeof( Hand ) )]
  922.     public class HandEditor : UnityEditor.Editor
  923.     {
  924.         //-------------------------------------------------
  925.         // Custom Inspector GUI allows us to click from within the UI
  926.         //-------------------------------------------------
  927.         public override void OnInspectorGUI()
  928.         {
  929.             DrawDefaultInspector();
  930.  
  931.             Hand hand = (Hand)target;
  932.  
  933.             if ( hand.otherHand )
  934.             {
  935.                 if ( hand.otherHand.otherHand != hand )
  936.                 {
  937.                     UnityEditor.EditorGUILayout.HelpBox( "The otherHand of this Hand's otherHand is not this Hand.", UnityEditor.MessageType.Warning );
  938.                 }
  939.  
  940.                 if ( hand.startingHandType == Hand.HandType.Left && hand.otherHand.startingHandType != Hand.HandType.Right )
  941.                 {
  942.                     UnityEditor.EditorGUILayout.HelpBox( "This is a left Hand but otherHand is not a right Hand.", UnityEditor.MessageType.Warning );
  943.                 }
  944.  
  945.                 if ( hand.startingHandType == Hand.HandType.Right && hand.otherHand.startingHandType != Hand.HandType.Left )
  946.                 {
  947.                     UnityEditor.EditorGUILayout.HelpBox( "This is a right Hand but otherHand is not a left Hand.", UnityEditor.MessageType.Warning );
  948.                 }
  949.  
  950.                 if ( hand.startingHandType == Hand.HandType.Any && hand.otherHand.startingHandType != Hand.HandType.Any )
  951.                 {
  952.                     UnityEditor.EditorGUILayout.HelpBox( "This is an any-handed Hand but otherHand is not an any-handed Hand.", UnityEditor.MessageType.Warning );
  953.                 }
  954.             }
  955.         }
  956.     }
  957. #endif
  958. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement