using System.Collections; using System.Collections.Generic; using UnityEngine; using Valve.VR; /** * This script was used inspired from Master Indie's tutorial on Youtube * Master Indie - How to GRAB RIGIDBODIES in VR! (Tutorial - Unity C# SteamVR) https://www.youtube.com/watch?v=nodALlM_IKY&t=200s&ab_channel=MasterIndie * It was modified and customized for our needs **/ public class PickUpHand : MonoBehaviour { public float distToPickup = 0.25f; bool handClosed = false; public LayerMask pickupLayer; public LayerMask bowLayer; public SteamVR_Action_Vibration hapticAction; public SteamVR_Input_Sources handSource = SteamVR_Input_Sources.RightHand; Rigidbody holdingTarget; // Update is called once per frame void FixedUpdate() { if (SteamVR_Actions.default_GrabPinch.GetState(handSource)) { handClosed = true; } else { handClosed = false; } if (!handClosed) { if (holdingTarget) { // Manage code for grabbable cranks GrabbableCrank gc = holdingTarget.GetComponent(); if (gc) { gc.ReleaseCrank(); } // Manage code for grabbable horn Horn horn = holdingTarget.GetComponent(); if (horn) { horn.Release(); } } if(Physics.OverlapSphere(transform.position, 0.1f, bowLayer).Length == 0) { Collider[] colliders = Physics.OverlapSphere(transform.position, distToPickup, pickupLayer); if (colliders.Length > 0) { holdingTarget = colliders[0].transform.GetComponent(); // Special management for the Horn if (holdingTarget.tag == "Horn") { if(Vector3.Distance(holdingTarget.position, transform.position) > (distToPickup/3)) { if (colliders.Length == 2) holdingTarget = colliders[1].transform.GetComponent(); else holdingTarget = null; } } } else holdingTarget = null; } else { holdingTarget = null; } } else { if (holdingTarget) { // Pulsate when handling crank if (holdingTarget.GetComponent()) { Pulse(0.1f, 160, 0.5f, SteamVR_Input_Sources.RightHand); AudioSource cranking= GameObject.Find("SFX/Cranking").GetComponent(); if (!cranking.isPlaying) cranking.Play(); } // Play arrow grabbing sound once if (holdingTarget.GetComponent()) { holdingTarget.GetComponent().PlayArrowGrabSFX(); } // Adjust velocity to move hand holdingTarget.velocity = (transform.position - holdingTarget.transform.position) / Time.fixedDeltaTime; // Adjust angular velocity to rotate to hand holdingTarget.maxAngularVelocity = 20; Quaternion toPosition = transform.rotation; // Rotate the arrow 90 degrees to match how you would normally grab an arrow if ((holdingTarget.transform.gameObject.tag == "arrow")) toPosition = transform.rotation * Quaternion.Euler(new Vector3(-90.0f, 0, 0)); if ((holdingTarget.transform.gameObject.tag == "Horn")) toPosition = transform.rotation * Quaternion.Euler(new Vector3(180.0f, 0, 0)); Quaternion deltaRot = toPosition * Quaternion.Inverse(holdingTarget.transform.rotation); Vector3 eulerRot = new Vector3(Mathf.DeltaAngle(0, deltaRot.eulerAngles.x), Mathf.DeltaAngle(0, deltaRot.eulerAngles.y), Mathf.DeltaAngle(0, deltaRot.eulerAngles.z)); eulerRot *= 0.95f; eulerRot *= Mathf.Deg2Rad; holdingTarget.angularVelocity = eulerRot / Time.fixedDeltaTime; } } } private void Pulse(float duration, float frequency, float amplitude, SteamVR_Input_Sources source) { hapticAction.Execute(0, duration, frequency, amplitude, source); } }