9 using System.Collections.Generic;
11 namespace Valve.VR.InteractionSystem
14 [RequireComponent( typeof( Interactable ) )]
17 public enum AttachMode
23 public float attachForce = 800.0f;
24 public float attachForceDamper = 25.0f;
26 public AttachMode attachMode = AttachMode.FixedJoint;
29 public Hand.AttachmentFlags attachmentFlags = 0;
31 private List<Hand> holdingHands =
new List<Hand>();
32 private List<Rigidbody> holdingBodies =
new List<Rigidbody>();
33 private List<Vector3> holdingPoints =
new List<Vector3>();
35 private List<Rigidbody> rigidBodies =
new List<Rigidbody>();
40 GetComponentsInChildren<Rigidbody>( rigidBodies );
47 for (
int i = 0; i < holdingHands.Count; i++ )
49 if ( !holdingHands[i].GetStandardInteractionButton() )
51 PhysicsDetach( holdingHands[i] );
58 private void OnHandHoverBegin(
Hand hand )
60 if ( holdingHands.IndexOf( hand ) == -1 )
62 if ( hand.controller != null )
64 hand.controller.TriggerHapticPulse( 800 );
71 private void OnHandHoverEnd(
Hand hand )
73 if ( holdingHands.IndexOf( hand ) == -1 )
75 if ( hand.controller != null )
77 hand.controller.TriggerHapticPulse( 500 );
84 private void HandHoverUpdate(
Hand hand )
86 if ( hand.GetStandardInteractionButtonDown() )
88 PhysicsAttach( hand );
94 private void PhysicsAttach(
Hand hand )
96 PhysicsDetach( hand );
98 Rigidbody holdingBody = null;
99 Vector3 holdingPoint = Vector3.zero;
102 float closestDistance = float.MaxValue;
103 for (
int i = 0; i < rigidBodies.Count; i++ )
105 float distance = Vector3.Distance( rigidBodies[i].worldCenterOfMass, hand.transform.position );
106 if ( distance < closestDistance )
108 holdingBody = rigidBodies[i];
109 closestDistance = distance;
114 if ( holdingBody == null )
118 if ( attachMode == AttachMode.FixedJoint )
120 Rigidbody handRigidbody = Util.FindOrAddComponent<Rigidbody>( hand.gameObject );
121 handRigidbody.isKinematic =
true;
123 FixedJoint handJoint = hand.gameObject.AddComponent<FixedJoint>();
124 handJoint.connectedBody = holdingBody;
128 hand.HoverLock( null );
131 Vector3 offset = hand.transform.position - holdingBody.worldCenterOfMass;
132 offset = Mathf.Min( offset.magnitude, 1.0f ) * offset.normalized;
133 holdingPoint = holdingBody.transform.InverseTransformPoint( holdingBody.worldCenterOfMass + offset );
135 hand.AttachObject( this.gameObject, attachmentFlags );
138 holdingHands.Add( hand );
139 holdingBodies.Add( holdingBody );
140 holdingPoints.Add( holdingPoint );
145 private bool PhysicsDetach(
Hand hand )
147 int i = holdingHands.IndexOf( hand );
152 holdingHands[i].DetachObject( this.gameObject, false );
155 holdingHands[i].HoverUnlock( null );
158 if ( attachMode == AttachMode.FixedJoint )
160 Destroy( holdingHands[i].GetComponent<FixedJoint>() );
163 Util.FastRemove( holdingHands, i );
164 Util.FastRemove( holdingBodies, i );
165 Util.FastRemove( holdingPoints, i );
177 if ( attachMode == AttachMode.Force )
179 for (
int i = 0; i < holdingHands.Count; i++ )
181 Vector3 targetPoint = holdingBodies[i].transform.TransformPoint( holdingPoints[i] );
182 Vector3 vdisplacement = holdingHands[i].transform.position - targetPoint;
184 holdingBodies[i].AddForceAtPosition( attachForce * vdisplacement, targetPoint, ForceMode.Acceleration );
185 holdingBodies[i].AddForceAtPosition( -attachForceDamper * holdingBodies[i].GetPointVelocity( targetPoint ), targetPoint, ForceMode.Acceleration );