212 lines
6.1 KiB
C#
212 lines
6.1 KiB
C#
using System.Collections;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using Valve.VR;
|
|
|
|
public class Arrow : MonoBehaviour
|
|
{
|
|
//Default arrows values based on this https://www.bowhunter.com/editorial/heavy-vs-light-choosing-the-best-hunting-arrow/182978 with the 480gr
|
|
public float m_MaxLaunchSpeedMeterPerSecond = 88.392f;
|
|
public float m_Mass = 0.0311035f;
|
|
public Transform m_Tip = null;
|
|
public GameObject hay;
|
|
public bool hasHayOn = false;
|
|
public GameObject fireParticles;
|
|
public GameObject explosionFX;
|
|
public SteamVR_Action_Vibration hapticAction;
|
|
|
|
public Rigidbody m_Rigidbody = null;
|
|
private bool m_isStopped = true;
|
|
private Vector3 m_LastPosition = Vector3.zero;
|
|
|
|
private bool startIgnitionTime = false;
|
|
public bool onFire = false;
|
|
private float timer = 0.0f;
|
|
private bool arrowGrabbed = false;
|
|
|
|
public int arrowDamage = 1;
|
|
|
|
private void Awake() {
|
|
m_Rigidbody = GetComponent<Rigidbody>();
|
|
m_Rigidbody.mass = m_Mass;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
m_LastPosition = transform.position;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (startIgnitionTime)
|
|
{
|
|
if (hasHayOn)
|
|
{
|
|
if (!onFire)
|
|
{
|
|
Pulse(0.1f, 160, 1, SteamVR_Input_Sources.RightHand);
|
|
timer += Time.deltaTime;
|
|
if (timer >= 1.5f)
|
|
{
|
|
ActivateFireFX();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (m_isStopped)
|
|
return;
|
|
|
|
// Rotate
|
|
m_Rigidbody.MoveRotation(Quaternion.LookRotation(m_Rigidbody.velocity, transform.up) * Quaternion.Euler(270.0f, 0, 0));
|
|
|
|
// Collision
|
|
RaycastHit hit;
|
|
if (Physics.Linecast(m_LastPosition, m_Tip.position, out hit, 1<<0 | 1<<4 | 1<<8 | 1<<9 | 1<<10)) // Default, Water, Ground, Mountain, NotWalkable
|
|
{
|
|
GameObject go = hit.collider.gameObject;
|
|
Stop(go);
|
|
CheckDamage(go);
|
|
}
|
|
|
|
// Store position
|
|
m_LastPosition = m_Tip.position;
|
|
}
|
|
|
|
private void Stop(GameObject hitObject)
|
|
{
|
|
m_isStopped = true;
|
|
|
|
transform.parent = hitObject.transform;
|
|
|
|
m_Rigidbody.isKinematic = true;
|
|
m_Rigidbody.useGravity = false;
|
|
|
|
CheckDamage(hitObject);
|
|
|
|
if(hitObject.tag == "OilPool" && hasHayOn && onFire)
|
|
{
|
|
StartCoroutine(FireArrowHitOil(hitObject));
|
|
}
|
|
}
|
|
|
|
private void CheckDamage(GameObject hitObject)
|
|
{
|
|
MonoBehaviour[] behaviours = hitObject.GetComponents<MonoBehaviour>();
|
|
|
|
foreach(MonoBehaviour behaviour in behaviours)
|
|
{
|
|
if (behaviour is EnemyBodyPart damageable)
|
|
{
|
|
damageable.Damage(arrowDamage, onFire);
|
|
break;
|
|
}
|
|
|
|
if (behaviour is DamageableObject damageablObjecte)
|
|
{
|
|
damageablObjecte.Damage(onFire, gameObject);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Fire(float pullValue, AudioSource audioSource)
|
|
{
|
|
Vector3 parentForward = transform.parent.forward;
|
|
Fire(pullValue, parentForward, audioSource);
|
|
}
|
|
|
|
public void Fire(float pullValue, Vector3 parentForward, AudioSource audioSource)
|
|
{
|
|
audioSource.Play();
|
|
m_LastPosition = transform.position;
|
|
|
|
m_isStopped = false;
|
|
transform.SetParent(null, true);
|
|
|
|
m_Rigidbody.isKinematic = false;
|
|
m_Rigidbody.useGravity = true;
|
|
m_Rigidbody.AddForce(parentForward * pullValue * m_MaxLaunchSpeedMeterPerSecond * m_Mass / Time.fixedDeltaTime);
|
|
|
|
Destroy(gameObject, 5.0f);
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
if(other.gameObject.tag == "hayBucket")
|
|
{
|
|
Pulse(0.5f, 160, 1, SteamVR_Input_Sources.RightHand);
|
|
AddHayOnTip();
|
|
GameObject.Find("SFX/WheatCrunch").GetComponent<AudioSource>().Play();
|
|
}
|
|
else if(other.gameObject.tag == "Fx")
|
|
{
|
|
startIgnitionTime = true;
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
if (other.gameObject.tag == "Fx")
|
|
{
|
|
//Set fire particle on arrow tip
|
|
startIgnitionTime = false;
|
|
}
|
|
}
|
|
|
|
public void AddHayOnTip()
|
|
{
|
|
GameObject hayOnArrow = Instantiate(hay, m_Tip);
|
|
hayOnArrow.transform.localPosition = new Vector3(0, 0, 0);
|
|
hayOnArrow.transform.localEulerAngles = Vector3.zero;
|
|
hasHayOn = true;
|
|
}
|
|
|
|
public void ActivateFireFX()
|
|
{
|
|
onFire = true;
|
|
fireParticles.SetActive(true);
|
|
GameObject.Find("SFX/ArrowIgnition").GetComponent<AudioSource>().Play();
|
|
}
|
|
|
|
private IEnumerator FireArrowHitOil(GameObject collider)
|
|
{
|
|
yield return new WaitForSeconds(1.0f);
|
|
GameObject explosion = Instantiate(explosionFX);
|
|
explosion.transform.position = collider.transform.position;
|
|
collider.GetComponent<AudioSource>().Play();
|
|
|
|
Enemy[] enemies = FindObjectsOfType(typeof(Enemy)) as Enemy[];
|
|
foreach (Enemy enemy in enemies)
|
|
{
|
|
if (Vector3.Distance(enemy.transform.position, transform.position) < 4.0f)
|
|
enemy.Kill(true, false);
|
|
else if (Vector3.Distance(enemy.transform.position, transform.position) >= 4.0f && Vector3.Distance(enemy.transform.position, transform.position) < 6.0f)
|
|
enemy.TakeDamage(1, true, false);
|
|
}
|
|
|
|
// PoolEmitter
|
|
collider.transform.parent.gameObject.GetComponent<ParticleSystem>().Play();
|
|
Destroy(collider, 2.5f);
|
|
Destroy(explosion, 2.5f);
|
|
}
|
|
|
|
private void Pulse(float duration, float frequency, float amplitude, SteamVR_Input_Sources source)
|
|
{
|
|
hapticAction.Execute(0, duration, frequency, amplitude, source);
|
|
}
|
|
|
|
public void PlayArrowGrabSFX()
|
|
{
|
|
if (!arrowGrabbed)
|
|
{
|
|
arrowGrabbed = true;
|
|
GameObject.Find("SFX/GrabArrow").GetComponent<AudioSource>().Play();
|
|
}
|
|
}
|
|
|
|
}
|