using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR; using Valve.VR; public class Bow : MonoBehaviour { [Header("Assets")] public GameObject m_ArrowPrefab = null; public GameObject m_Quiver = null; [Header("Bow")] public float m_GrabThreshold = 0.15f; public Transform m_Start = null; public Transform m_End = null; public Transform m_Socket = null; public AudioSource m_bowShootingSound; private Transform m_PullingHand = null; private Arrow m_CurrentArrow = null; private bool m_ArrowInstanciated = false; private Animator m_Animator = null; private ArcPrediction m_Predictor = null; private float m_ArrowReleaseTreshold = 0.15f; private bool isBeingPulled = false; public SteamVR_Action_Vibration hapticAction; private float m_PullValue = 0.0f; private void Awake() { m_Predictor = GetComponent(); m_Predictor.HideArc(); m_Animator = GetComponent(); } private void Start() { StartCoroutine(CreateArrow(0.0f)); Physics.IgnoreLayerCollision(6, 6); } private void Update() { if (!m_PullingHand || !m_CurrentArrow) return; m_PullValue = CalculatePull(m_PullingHand); m_PullValue = Mathf.Clamp(m_PullValue, 0.0f, 1.0f); if (m_PullValue > 0.2f) { if (!GameObject.Find("SFX/ArrowPull").GetComponent().isPlaying && !isBeingPulled) { GameObject.Find("SFX/ArrowPull").GetComponent().Play(); isBeingPulled = true; } } else isBeingPulled = false; m_Animator.SetFloat("Blend", m_PullValue); if(m_PullValue > m_ArrowReleaseTreshold && GameManager.Instance.GetSubGameMode() == GameManager.SubGameMode.Arcade) { Pulse(0.1f, m_PullValue * 160, m_PullValue, SteamVR_Input_Sources.RightHand); Pulse(0.1f, m_PullValue * 160, m_PullValue, SteamVR_Input_Sources.LeftHand); m_Predictor.RenderArc(m_PullValue * m_CurrentArrow.m_MaxLaunchSpeedMeterPerSecond, 20, m_CurrentArrow.m_Rigidbody.rotation * Vector3.down); } else { m_Predictor.HideArc(); } } private float CalculatePull(Transform pullHand) { Vector3 direction = m_End.position - m_Start.position; float magnitude = direction.magnitude; direction.Normalize(); Vector3 difference = pullHand.position - m_Start.position; return Vector3.Dot(difference, direction) / magnitude; } private IEnumerator CreateArrow(float waitTime) { // Set the boolean to true m_ArrowInstanciated = true; // Wait yield return new WaitForSeconds(waitTime); // Create, child GameObject arrowObject = Instantiate(m_ArrowPrefab, m_Quiver.transform); // Orient arrowObject.transform.localPosition = new Vector3(m_Quiver.transform.localPosition.x - 0.1f, m_Quiver.transform.localPosition.y + 1.5f, m_Quiver.transform.localPosition.z + 0.45f); arrowObject.transform.localEulerAngles = Vector3.zero; } // Simple approach, think about possibly adding an interaction system public void Pull(Transform hand) { float distance = Vector3.Distance(hand.position, m_Start.position); if (distance > m_GrabThreshold) return; m_PullingHand = hand; } public void Release() { if (m_PullValue > m_ArrowReleaseTreshold) { FireArrow(); m_Predictor.HideArc(); } m_PullingHand = null; m_PullValue = 0; m_Animator.SetFloat("Blend", 0); if ((!m_CurrentArrow && !m_ArrowInstanciated) || (m_ArrowInstanciated && !m_CurrentArrow)) { Destroy(GameObject.FindGameObjectWithTag("arrow") ); StartCoroutine(CreateArrow(0.1f)); m_ArrowInstanciated = false; m_CurrentArrow = null; } } private void FireArrow() { m_CurrentArrow.Fire(m_PullValue, m_bowShootingSound); m_CurrentArrow = null; m_ArrowInstanciated = false; // Vibration [Removed by Joud: I added vibration depending on the pull value of the bow] // InputDevice m_left_controller = UnityEngine.XR.InputDevices.GetDeviceAtXRNode(UnityEngine.XR.XRNode.LeftHand); // InputDevice m_right_controller = UnityEngine.XR.InputDevices.GetDeviceAtXRNode(UnityEngine.XR.XRNode.RightHand); // if (m_left_controller.TryGetHapticCapabilities(out HapticCapabilities capabilities)) // if (capabilities.supportsImpulse) // m_left_controller.SendHapticImpulse(0, 0.5f, 0.5f); // if (m_right_controller.TryGetHapticCapabilities(out HapticCapabilities capabilitiesRight)) // if (capabilitiesRight.supportsImpulse) // m_right_controller.SendHapticImpulse(0, 1f, 0.2f); } private void OnTriggerEnter(Collider other) { if(other.gameObject.tag == "arrow") { gameObject.GetComponent().enabled = false; bool hasHayOn = other.gameObject.GetComponent().hasHayOn; bool onFire = other.gameObject.GetComponent().onFire; Destroy(other.gameObject); LockArrowOnBow(hasHayOn, onFire); } } private void LockArrowOnBow(bool hasHayOn, bool onFire) { GameObject.Find("SFX/ArrowFixedOnBow").GetComponent().Play(); GameObject arrowObject = Instantiate(m_ArrowPrefab, m_Socket); arrowObject.GetComponent().isKinematic = true; arrowObject.GetComponent().detectCollisions = false; arrowObject.tag = "Untagged"; arrowObject.transform.localPosition = new Vector3(0, 0, 0.425f); arrowObject.transform.Rotate(270.0f, 0, 0, Space.Self); //arrowObject.transform.localEulerAngles = Vector3.zero; m_CurrentArrow = arrowObject.GetComponent(); gameObject.GetComponent().enabled = true; if (hasHayOn) arrowObject.GetComponent().AddHayOnTip(); if (onFire) { Arrow arrowScript = arrowObject.GetComponent(); arrowScript.ActivateFireFX(); arrowScript.onFire = true; } } private void Pulse(float duration, float frequency, float amplitude, SteamVR_Input_Sources source) { hapticAction.Execute(0, duration, frequency, amplitude, source); } }