jimmy tremblay-Bernier 86fbe09b20 initial commit
2022-03-12 20:32:56 -05:00

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();
}
}
}