132 lines
3 KiB
C#
132 lines
3 KiB
C#
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
using Valve.VR;
|
|||
|
|
|||
|
public class Hand : MonoBehaviour
|
|||
|
{
|
|||
|
public SteamVR_Action_Boolean GrabAction = null;
|
|||
|
|
|||
|
private SteamVR_Behaviour_Pose Pose = null;
|
|||
|
private FixedJoint Joint = null;
|
|||
|
|
|||
|
private Interactable currentInteractable = null;
|
|||
|
public List<Interactable> contactInteractables = new List<Interactable>();
|
|||
|
|
|||
|
private void Awake()
|
|||
|
{
|
|||
|
Pose = GetComponent<SteamVR_Behaviour_Pose>();
|
|||
|
Joint = GetComponent<FixedJoint>();
|
|||
|
}
|
|||
|
|
|||
|
void Update()
|
|||
|
{
|
|||
|
// Down
|
|||
|
if (GrabAction.GetStateDown(Pose.inputSource))
|
|||
|
{
|
|||
|
print(Pose.inputSource + "TriggerDown");
|
|||
|
Pickup();
|
|||
|
}
|
|||
|
|
|||
|
// Up
|
|||
|
if (GrabAction.GetStateUp(Pose.inputSource))
|
|||
|
{
|
|||
|
print(Pose.inputSource + "TriggerUp");
|
|||
|
Drop();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void OnTriggerEnter(Collider other)
|
|||
|
{
|
|||
|
if (!other.gameObject.CompareTag("Interactable"))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
contactInteractables.Add(other.gameObject.GetComponent<Interactable>());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void OnTriggerExit(Collider other)
|
|||
|
{
|
|||
|
if (!other.gameObject.CompareTag("Interactable"))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
contactInteractables.Remove(other.gameObject.GetComponent<Interactable>());
|
|||
|
}
|
|||
|
|
|||
|
private void Pickup()
|
|||
|
{
|
|||
|
// Get nearest
|
|||
|
currentInteractable = GetNearestInteractable();
|
|||
|
|
|||
|
// Null check
|
|||
|
if (!currentInteractable)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Already held, check
|
|||
|
if (currentInteractable.ActiveHand)
|
|||
|
{
|
|||
|
currentInteractable.ActiveHand.Drop();
|
|||
|
}
|
|||
|
|
|||
|
// Position
|
|||
|
currentInteractable.transform.position = transform.position;
|
|||
|
|
|||
|
// Attach
|
|||
|
Rigidbody targetBody = currentInteractable.GetComponent<Rigidbody>();
|
|||
|
Joint.connectedBody = targetBody;
|
|||
|
|
|||
|
// Set active hand
|
|||
|
currentInteractable.ActiveHand = this;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void Drop()
|
|||
|
{
|
|||
|
// Null check
|
|||
|
if (!currentInteractable)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Apply velocity
|
|||
|
Rigidbody targetBody = currentInteractable.GetComponent<Rigidbody>();
|
|||
|
targetBody.velocity = Pose.GetVelocity();
|
|||
|
targetBody.angularVelocity = Pose.GetAngularVelocity();
|
|||
|
|
|||
|
// Detach
|
|||
|
Joint.connectedBody = null;
|
|||
|
|
|||
|
// Clear
|
|||
|
currentInteractable.ActiveHand = null;
|
|||
|
currentInteractable = null;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private Interactable GetNearestInteractable()
|
|||
|
{
|
|||
|
Interactable nearest = null;
|
|||
|
float minDistance = float.MaxValue;
|
|||
|
float distance = 0.0f;
|
|||
|
|
|||
|
foreach (Interactable interactable in contactInteractables)
|
|||
|
{
|
|||
|
distance = (interactable.transform.position - transform.position).sqrMagnitude;
|
|||
|
|
|||
|
if (distance<minDistance)
|
|||
|
{
|
|||
|
minDistance = distance;
|
|||
|
nearest = interactable;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nearest;
|
|||
|
}
|
|||
|
}
|