Unity with Vive VR Grab Dynamic Objects

smallarrows.GIF

In Unity:

Import a VR Camera and Sensors for Vive
     Choose Window->Asset Store

     Type Steam VR Plugin in the search bar, also select FREE ONLY button
unity_VR_steam_plugin
Select the
Steam VR Plugin (the free one by Valve Corporation) and Download

Choose Import
Choose Accept All and OK a few times

Put the main view window back to Scene instead of Asset Store

     Click the Scene tab on the left

Open the arrow on the SteamVR folder from the Project tab
Select Prefabs
Drag the CameraRig into the Hierarchy tab
In the Inspector tab under Steam VR_Play Area
change Size to Calibrated, this uses the calibrated area from the headset


Add RigidBodies and colliders to Vive hand held controllers
Open the arrow for CameraRig
in the Hierarchy tab choose both of the Controllers

In the Inspector tab
: select Add Component -> Physics->RigidBody
     Turn off  Use Gravity

In the Inspector tab: select Add Component -> Physics-> Box Collider
     Input Center:    X: 0   Y: -0.04   Z: .02
     Input Size:        X: 0.14   Y: 0.07   Z: 0.05

Turn on   Is Trigger
Is Trigger is for the grabbing

Add 1 more set of colliders to trigger your collisions and animations.
In the Inspector tab: select Add Component -> Physics-> Box Collider
     Input Center:    X: 0   Y: -0.04   Z: .02
     Input Size:        X: 0.13   Y: 0.06   Z: 0.04


Add this C# script caller ControllerGrabObject to your triggers

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ControllerGrabObject : MonoBehaviour {

 
private SteamVR_TrackedObject trackedObj;

 
// 1
 private GameObject collidingObject;
 
// 2
 private GameObject objectInHand;


 
private SteamVR_Controller.Device Controller
 {
 
get { return SteamVR_Controller.Input((int)trackedObj.index); }
 }

 
void Awake()
 {
  trackedObj = GetComponent<
SteamVR_TrackedObject>();
 }

 
private void SetCollidingObject(Collider col)
 {
 
// 1
  if (collidingObject || !col.GetComponent<Rigidbody>())
  {
  
return;
  }
 
// 2
  collidingObject = col.gameObject;
 }
 
 
// 1
 public void OnTriggerEnter(Collider other)
 {
  SetCollidingObject(other);
 }

 
// 2
 public void OnTriggerStay(Collider other)
 {
  SetCollidingObject(other);
 }

 
// 3
 public void OnTriggerExit(Collider other)
 {
 
if (!collidingObject)
  {
  
return;
  }

  collidingObject =
null;
 }
 
 
private void GrabObject()
 {
 
// 1
  objectInHand = collidingObject;
  collidingObject =
null;
 
// 2
  var joint = AddFixedJoint();
  joint.connectedBody = objectInHand.GetComponent<
Rigidbody>();
 }

 
// 3
 private FixedJoint AddFixedJoint()
 {
 
FixedJoint fx = gameObject.AddComponent<FixedJoint>();
  fx.breakForce =
20000;
  fx.breakTorque =
20000;
 
return fx;
 }
 
 
private void ReleaseObject()
 {
 
// 1
  if (GetComponent<FixedJoint>())
  {
  
// 2
   GetComponent<FixedJoint>().connectedBody = null;
   Destroy(GetComponent<
FixedJoint>());
  
// 3
   objectInHand.GetComponent<Rigidbody>().velocity = Controller.velocity;
   objectInHand.GetComponent<
Rigidbody>().angularVelocity = Controller.angularVelocity;
  }
 
// 4
  objectInHand = null;
 }
 
 
// Update is called once per frame
 void Update () {
 
// 1
 if (Controller.GetHairTriggerDown())
 {
 
if (collidingObject)
  {
   GrabObject();
  }
 }

 
// 2
 if (Controller.GetHairTriggerUp())
 {
 
if (objectInHand)
  {
   ReleaseObject();
  }
 }
}
}