Skip to content

Instantly share code, notes, and snippets.

@bddckr
Last active March 1, 2017 20:26
Show Gist options
  • Save bddckr/ec784df8500e5826d71487f35585c7a0 to your computer and use it in GitHub Desktop.
Save bddckr/ec784df8500e5826d71487f35585c7a0 to your computer and use it in GitHub Desktop.
using System;
using UnityEngine;
using VRTK;
[RequireComponent(typeof(VRTK_InteractGrab))]
public class InteractableObjectGrabHook : MonoBehaviour
{
[Tooltip("How long a complete move of the interactable object should take (in either direction).")]
public float Duration;
private enum GrabState
{
None,
Grabbed,
Ungrabbed
}
private VRTK_InteractGrab grabScript;
private GrabState grabState = GrabState.None;
private Rigidbody grabbedRigidbody;
private Rigidbody grabbingRigidbody;
private Vector3 grabStartPosition;
private float grabStartTime;
private void OnEnable()
{
grabScript = GetComponent<VRTK_InteractGrab>();
grabScript.ControllerGrabInteractableObject += OnControllerGrabInteractableObject;
grabScript.ControllerUngrabInteractableObject += OnControllerUngrabInteractableObject;
}
private void OnDisable()
{
grabScript.ControllerGrabInteractableObject -= OnControllerGrabInteractableObject;
grabScript.ControllerUngrabInteractableObject -= OnControllerUngrabInteractableObject;
grabScript = null;
grabState = GrabState.None;
grabbedRigidbody = null;
grabbingRigidbody = null;
grabStartTime = Time.time;
}
private void FixedUpdate()
{
switch (grabState)
{
case GrabState.Grabbed:
if (Vector3.Distance(grabbedRigidbody.position, grabbingRigidbody.position) < float.Epsilon)
{
grabState = GrabState.None;
return;
}
var timeSinceGrabStart = Time.time - grabStartTime;
var grabMovementPercentageComplete = timeSinceGrabStart / Duration;
grabbedRigidbody.MovePosition(
Vector3.Lerp(
grabStartPosition,
grabbingRigidbody.position,
grabMovementPercentageComplete
)
);
break;
case GrabState.Ungrabbed:
if (Vector3.Distance(grabbedRigidbody.position, grabStartPosition) < float.Epsilon)
{
grabState = GrabState.None;
return;
}
var timeSinceUngrabStart = Time.time - grabStartTime;
var ungrabMovementPercentageComplete = timeSinceUngrabStart / Duration;
grabbedRigidbody.MovePosition(
Vector3.Lerp(
grabbingRigidbody.position,
grabStartPosition,
ungrabMovementPercentageComplete
)
);
break;
case GrabState.None:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void OnControllerGrabInteractableObject(object sender, ObjectInteractEventArgs objectInteractEventArgs)
{
grabState = GrabState.Grabbed;
grabbedRigidbody = objectInteractEventArgs.target.GetComponent<Rigidbody>();
grabbingRigidbody = VRTK_DeviceFinder.GetControllerByIndex(objectInteractEventArgs.controllerIndex, false)
.gameObject.GetComponent<Rigidbody>();
grabStartPosition = grabbedRigidbody.position;
grabStartTime = Time.time;
}
private void OnControllerUngrabInteractableObject(object sender, ObjectInteractEventArgs objectInteractEventArgs)
{
grabState = GrabState.Ungrabbed;
grabStartTime = Time.time;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment