Files
ZeroVR/ZeroPacientVR/Assets/Scripts/VR/GrenadeWeapon.cs
T

217 lines
6.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using FMOD.Studio;
using FMODUnity;
using HurricaneVR.Framework.Components;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Weapons;
using UnityEngine;
using STOP_MODE = FMOD.Studio.STOP_MODE;
public class GrenadeWeapon : MonoBehaviour
{
[Header("Grenade")]
[SerializeField] private float delayToDamage = 0.2f;
[SerializeField] private LayerMask mask;
[SerializeField] private float radius;
[SerializeField] private float upDistance = 1f;
[SerializeField] private float delayToExplosion;
[SerializeField] private HVRDamageProvider damageProvider;
[SerializeField] private List<Collider> toCheckColliders;
[Header("Sound")]
[SerializeField] private EventReference soundRef;
[SerializeField] private AnimationCurve soundCurve;
private EventInstance soundInstance;
[Header("Setup")]
[SerializeField] private HVRGrabbable grabbable;
[SerializeField] private GrenadeActivator activator;
[SerializeField] private GameObject explosionFx;
[SerializeField] private HVRGunSounds sounds;
[SerializeField] private Renderer buttonRender;
[SerializeField] private Material buttonMaterial;
[SerializeField] private float offset;
[SerializeField] private Color emissionColor;
[SerializeField] private bool isDebug;
private static readonly int emissionColorId = Shader.PropertyToID("_EmissionColor");
private bool isReady;
private void Start()
{
soundInstance = RuntimeManager.CreateInstance(soundRef);
RuntimeManager.AttachInstanceToGameObject(soundInstance, gameObject.transform);
buttonMaterial = buttonRender.material;
activator.OnReady += OnReady;
grabbable.HandGrabbed.AddListener(Grab);
grabbable.HandReleased.AddListener(Release);
}
private void OnDestroy()
{
activator.OnReady -= OnReady;
grabbable.HandGrabbed.RemoveListener(Grab);
grabbable.HandReleased.RemoveListener(Release);
}
private void Grab(HVRHandGrabber arg0, HVRGrabbable hvrGrabbable)
{
}
private void Release(HVRGrabberBase arg0, HVRGrabbable hvrGrabbable)
{
if(isReady)
{
OnActivator();
isReady = false;
}
}
private void OnReady()
{
sounds.PlaySlideForward();
StartCoroutine(Ready());
}
IEnumerator Ready()
{
activator.OnReady -= OnReady;
isReady = true;
soundInstance.stop(STOP_MODE.IMMEDIATE);
soundInstance.start();
var t = 0f;
var inverse = false;
while(t >= 0f)
{
if(!inverse) t += Time.deltaTime;
if(inverse) t -= Time.deltaTime;
if(t >= 1f)
{
t = 1f;
inverse = true;
}
t = Mathf.Clamp01(t);
var c = emissionColor * t;
buttonMaterial.SetVector(emissionColorId, c);
yield return null;
}
soundInstance.stop(STOP_MODE.IMMEDIATE);
}
private void OnActivator()
{
StartCoroutine(WaitAndExplosion());
}
private IEnumerator WaitAndExplosion()
{
var t = 0f;
var soundActivate = false;
while(t <= delayToExplosion)
{
t += Time.deltaTime;
var ev = soundCurve.Evaluate(t);
if(ev > 0.9f && !soundActivate)
{
soundActivate = true;
soundInstance.stop(STOP_MODE.IMMEDIATE);
soundInstance.start();
}
else if(ev < 0.8 && soundActivate)
{
soundActivate = false;
}
var c = emissionColor * ev;
buttonMaterial.SetVector(emissionColorId, c);
yield return null;
}
soundInstance.stop(STOP_MODE.IMMEDIATE);
soundInstance.release();
IEnumerator DelayHit()
{
yield return new WaitForSeconds(delayToDamage);
var hits = PhysicsExtension.SphereCastAll(transform.position, radius, Vector3.up, upDistance, mask, QueryTriggerInteraction.Ignore);
foreach(var raycastHit in hits)
{
var handler = raycastHit.collider.GetComponent<HVRDamageHandlerBase>();
if(handler)
{
var position = transform.position;
var dir = (position - raycastHit.point).normalized;
var ray = new Ray(raycastHit.point + dir * offset, dir);
var isRay = Physics.Raycast(ray, out var rayHit, Mathf.Infinity, mask, QueryTriggerInteraction.Ignore);
if(isRay)
{
if(toCheckColliders.Contains(rayHit.collider))
{
handler.HandleRayCastHit(damageProvider, raycastHit);
handler.HandleDamageProvider(damageProvider, raycastHit.point, dir.normalized);
}
}
}
}
Destroy(gameObject);
}
StartCoroutine(DelayHit());
var expInstantiate = Instantiate(explosionFx, transform.position, Quaternion.identity);
Destroy(expInstantiate, 2f);
}
private void OnDrawGizmos()
{
if (!isDebug) return;
var color = Gizmos.color;
Gizmos.DrawWireSphere(transform.position, radius);
var hits = PhysicsExtension.SphereCastAll(transform.position, radius, Vector3.up, upDistance, mask, QueryTriggerInteraction.Ignore);
foreach(var raycastHit in hits)
{
var handler = raycastHit.collider.GetComponent<HVRDamageHandlerBase>();
if(handler)
{
var position = transform.position;
var dir = (position - raycastHit.point).normalized;
var ray = new Ray(raycastHit.point + dir * offset, dir);
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(raycastHit.point, 0.05f);
var isRay = Physics.Raycast(ray, out var rayHit, Mathf.Infinity, mask, QueryTriggerInteraction.Ignore);
if(isRay)
{
if(toCheckColliders.Contains(rayHit.collider))
{
Debug.DrawLine(raycastHit.point, rayHit.point);
}
else
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(rayHit.point, 0.05f);
Debug.DrawLine(raycastHit.point, rayHit.point);
}
}
}
}
Gizmos.color = color;
}
}