193 lines
6.5 KiB
C#
193 lines
6.5 KiB
C#
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<ArcPrediction>();
|
|
m_Predictor.HideArc();
|
|
m_Animator = GetComponent<Animator>();
|
|
}
|
|
|
|
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<AudioSource>().isPlaying && !isBeingPulled)
|
|
{
|
|
GameObject.Find("SFX/ArrowPull").GetComponent<AudioSource>().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<SphereCollider>().enabled = false;
|
|
bool hasHayOn = other.gameObject.GetComponent<Arrow>().hasHayOn;
|
|
bool onFire = other.gameObject.GetComponent<Arrow>().onFire;
|
|
Destroy(other.gameObject);
|
|
LockArrowOnBow(hasHayOn, onFire);
|
|
}
|
|
}
|
|
|
|
private void LockArrowOnBow(bool hasHayOn, bool onFire)
|
|
{
|
|
GameObject.Find("SFX/ArrowFixedOnBow").GetComponent<AudioSource>().Play();
|
|
GameObject arrowObject = Instantiate(m_ArrowPrefab, m_Socket);
|
|
arrowObject.GetComponent<Rigidbody>().isKinematic = true;
|
|
arrowObject.GetComponent<Rigidbody>().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<Arrow>();
|
|
gameObject.GetComponent<SphereCollider>().enabled = true;
|
|
|
|
if (hasHayOn) arrowObject.GetComponent<Arrow>().AddHayOnTip();
|
|
if (onFire)
|
|
{
|
|
Arrow arrowScript = arrowObject.GetComponent<Arrow>();
|
|
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);
|
|
}
|
|
}
|