Created
May 27, 2018 02:00
-
-
Save chrisforbes/d04b0d6938cfb63c5df214e1411d5e71 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; | |
public class HandGrab : MonoBehaviour | |
{ | |
SteamVR_TrackedObject trackedObj; | |
SteamVR_Controller.Device controller { get { return SteamVR_Controller.Input((int)trackedObj.index); } } | |
GameObject pickUp; | |
ConfigurableJoint joint, joint2; | |
public TextMesh describe; | |
void Start() | |
{ | |
trackedObj = GetComponent<SteamVR_TrackedObject>(); | |
pickUp = null; | |
} | |
Transform GetRoot(GameObject o) | |
{ | |
var t = o.transform; | |
while (t.parent != null) | |
t = t.parent; | |
return t; | |
} | |
void OnTriggerEnter(Collider collider) | |
{ | |
// don't consider anything that's in our hierarchy. we don't want the hands | |
// to collide with themselves, with each other, with the body, etc... | |
// DONT do this using collision layers - we don't know how many players there will be. | |
if (GetRoot(collider.gameObject) == GetRoot(gameObject)) | |
return; | |
// don't consider things that are not rigid bodies. we /might/ be able to fix this in future | |
// to use layers. | |
if (collider.gameObject.GetComponent<Rigidbody>() == null) | |
return; | |
pickUp = collider.gameObject; | |
} | |
void OnTriggerExit(Collider collider) | |
{ | |
if (pickUp == collider.gameObject) | |
pickUp = null; | |
} | |
void ConfigureJoint(float mass, bool driveRotation, ConfigurableJoint j) | |
{ | |
var springFactor = 3000f; | |
var damperFactor = 10f; | |
var maxForceFactor = 70f; | |
var breakFactor = 150f; | |
JointDrive drive = j.xDrive; | |
drive.positionSpring = springFactor * mass; | |
drive.positionDamper = damperFactor * mass; | |
drive.maximumForce = maxForceFactor * mass; | |
j.xDrive = drive; | |
drive = j.yDrive; | |
drive.positionSpring = springFactor * mass; | |
drive.positionDamper = damperFactor * mass; | |
drive.maximumForce = maxForceFactor * mass; | |
j.yDrive = drive; | |
drive = j.zDrive; | |
drive.positionSpring = springFactor * mass; | |
drive.positionDamper = damperFactor * mass; | |
drive.maximumForce = maxForceFactor * mass; | |
j.zDrive = drive; | |
if (driveRotation) | |
{ | |
var angularSpringFactor = 30f; | |
var angularDamperFactor = 1f; | |
j.rotationDriveMode = RotationDriveMode.XYAndZ; | |
drive = j.angularYZDrive; | |
drive.positionSpring = angularSpringFactor * mass; | |
drive.positionDamper = angularDamperFactor * mass; | |
j.angularYZDrive = drive; | |
drive = j.angularXDrive; | |
drive.positionSpring = angularSpringFactor * mass; | |
drive.positionDamper = angularDamperFactor * mass; | |
j.angularXDrive = drive; | |
} | |
j.breakForce = breakFactor * mass; | |
} | |
Vector3 grabPoint; | |
Quaternion grabOrientation; | |
void Update() | |
{ | |
if (controller.GetPressDown(Valve.VR.EVRButtonId.k_EButton_Grip) && pickUp != null) | |
{ | |
var rb = pickUp.GetComponent<Rigidbody>(); | |
if (rb.isKinematic) | |
{ | |
// this constraint will allow us to pull/push ourselves through the space. | |
var rootGameObject = GetRoot(gameObject).gameObject; | |
if (joint2 == null) | |
joint2 = rootGameObject.AddComponent<ConfigurableJoint>(); | |
joint2.connectedBody = null; | |
joint2.anchor = transform.localPosition; | |
grabPoint = transform.localPosition; | |
grabOrientation = transform.localRotation; | |
joint2.connectedAnchor = new Vector3(0, 0, 0); | |
joint2.autoConfigureConnectedAnchor = false; | |
joint2.configuredInWorldSpace = false; | |
ConfigureJoint(rootGameObject.GetComponent<Rigidbody>().mass, true, joint2); | |
} | |
else | |
{ | |
// this constraint will allow us to hold a free object. | |
if (joint == null) | |
joint = gameObject.AddComponent<ConfigurableJoint>(); | |
joint.connectedBody = rb; | |
ConfigureJoint(rb.mass, true, joint); | |
} | |
} | |
if (joint2 != null) | |
{ | |
joint2.targetPosition = transform.localPosition - grabPoint; | |
joint2.targetRotation = transform.localRotation * Quaternion.Inverse(grabOrientation); | |
} | |
if (controller.GetPressUp(Valve.VR.EVRButtonId.k_EButton_Grip)) | |
{ | |
if (joint != null) | |
{ | |
Destroy(joint); | |
joint = null; | |
} | |
if (joint2 != null) | |
{ | |
Destroy(joint2); | |
joint2 = null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment