217 lines
6.9 KiB
C#
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;
|
|
}
|
|
}
|