using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.XR.Interaction.Toolkit; public class LeverController : MonoBehaviour { private Transform pivot; //The lever will use a pivot point private Transform grabHand; private bool leverGrabbed; private bool eventCalled; private bool leverDown; private Vector3 handDelta; private Vector3 lastPosition; //These UnityEvent objects can be set in the inspector as any public methods from scripts [SerializeField] private UnityEvent onUp; [SerializeField] private UnityEvent onDown; public float minAngle = 20f; public float maxAngle = 75f; public float hapticAmplitude = 1f; public float hapticDuration = 0.1f; public AudioSource upSound; public AudioSource downSound; //This script cannot work with multiplayer, see CheckHand() method public Transform leftHand; public Transform rightHand; void Awake() { pivot = transform.parent; leverGrabbed = false; leverDown = false; pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, minAngle); leftHand = GameObject.Find("LeftHand Controller").transform; rightHand = GameObject.Find("RightHand Controller").transform; } void Update() { if (leverGrabbed) { handDelta = lastPosition - grabHand.position; //The vector of hand movement between frames pivot.RotateAround(pivot.position, pivot.forward, 200 * handDelta.y); //Is a Time.deltaTime multiplication needed here? //Two following if statements set the up and down position angles and call events when angle is met //Only one event is called per grab because the logic is in the update method if(pivot.eulerAngles.z < minAngle) { pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, minAngle); if (leverDown) { onUp.Invoke(); grabHand.gameObject.GetComponent().SendHapticImpulse(hapticAmplitude, hapticDuration); if (upSound != null) upSound.Play(); leverDown = false; } } else if(pivot.eulerAngles.z > maxAngle) { pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, maxAngle); if (!leverDown) { onDown.Invoke(); grabHand.gameObject.GetComponent().SendHapticImpulse(hapticAmplitude, hapticDuration); if (downSound != null) downSound.Play(); leverDown = true; } } lastPosition = grabHand.position; } } public void GrabLever() { CheckHand(); leverGrabbed = !leverGrabbed; handDelta = Vector3.zero; lastPosition = grabHand.position; eventCalled = false; } private void CheckHand() { float leftDistance = Vector3.Distance(leftHand.position, transform.position); float rightDistance = Vector3.Distance(rightHand.position, transform.position); if (leftDistance > rightDistance) grabHand = rightHand; else grabHand = leftHand; } }