holopy3/Assets/Scripts/Hand.cs

132 lines
3 KiB
C#
Raw Normal View History

2020-12-10 14:25:12 +00:00
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;
}
}