ZeroVR/ZeroPacientVR/Assets/Scripts/Npc/NpcCombatParazit.cs

179 lines
4.7 KiB
C#

using System.Collections;
using FMODUnity;
using HurricaneVR.Framework.Components;
using NodeCanvas.Framework;
using UnityEngine;
using Zero;
using Random = UnityEngine.Random;
public class NpcCombatParazit : NpcCombatAbstract
{
[SerializeField] private Animator animator;
[SerializeField] private float health = 20;
[SerializeField] private float cooldownTimeAttack = 2f;
[SerializeField] private float cooldownTimeAggressiveAnim = 2f;
[SerializeField] private ExtGunBase weapon;
[SerializeField] private GameObject explosionPrefab;
[SerializeField] private EventReference attackClip;
[SerializeField] private EventReference aggressiveClip;
[SerializeField] private Dissolver dissolver;
private bool isAggressiveAnimState;
private bool isAttackAnimState;
private float nextTime;
private float nextTimeAggressive;
private static readonly int AttackAnim = Animator.StringToHash("Attack");
private static readonly int AggressiveAnim = Animator.StringToHash("Aggressive");
private static readonly int IdleIdAnim = Animator.StringToHash("IdleId");
private Status status;
private Status nextStatus;
private Transform targetToAim;
private bool isRange;
public override Status ResetCooldown()
{
nextTime = cooldownTimeAttack;
return Status.Success;
}
public override Status UpdateTime()
{
nextTime += Time.deltaTime;
nextTimeAggressive += Time.deltaTime;
UpdateCombatTime();
return Status.Success;
}
public override Status Attack(GameObject target, bool isRange)
{
SetCombatState();
StartCoroutine(AttackState(target.transform, isRange));
return status;
}
public override Status Aggressive()
{
IsAggressiveMode = true;
StartCoroutine(PlayAggressiveAnim());
return status;
}
public override Status GetAttackStatus()
{
if (nextTime < cooldownTimeAttack) return Status.Running;
return Status.Success;
}
public override float GetHealth()
{
return health;
}
IEnumerator PlayAggressiveAnim()
{
if (status == Status.Running)
{
yield break;
}
if (!isAggressiveAnimState)
{
status = Status.Running;
yield return null;
isAggressiveAnimState = true;
animator.SetTrigger(AggressiveAnim);
if (!aggressiveClip.IsNull) RuntimeManager.PlayOneShot(aggressiveClip, transform.position);
yield return null;
yield return new WaitForSeconds(1f);
status = Status.Success;
}
if (nextTimeAggressive >= cooldownTimeAggressiveAnim)
{
nextTimeAggressive = 0;
isAggressiveAnimState = false;
}
yield return null;
}
IEnumerator AttackState(Transform target, bool isRange)
{
if ((!isAggressiveAnimState && IsAggressiveMode) || status == Status.Running)
{
yield break;
}
if (nextTime >= cooldownTimeAttack)
{
targetToAim = target;
status = Status.Running;
this.isRange = isRange;
animator.SetTrigger(AttackAnim);
yield return new WaitUntil(() => targetToAim == null);
status = Status.Success;
nextTime = 0;
animator.SetInteger(IdleIdAnim, Random.Range(0, 2));
}
yield return null;
}
private void UpdateAim(Transform target)
{
var playerTarget = target.GetComponent<PlayerTargetPosition>();
if (playerTarget)
{
target = playerTarget.GetTarget();
}
weapon.transform.LookAt(target);
}
public void OnHit(HVRDamageProvider damageProvider, RaycastHit hit)
{
health -= damageProvider.Damage;
if(health <= 0)
{
health = 0;
if(explosionPrefab)
{
var explosion = Instantiate(explosionPrefab, transform.position, Quaternion.identity);
Destroy(explosion, 2f);
explosionPrefab = null;
}
if (dissolver) dissolver.Enabled();
Destroy(gameObject, 2f);
}
else
{
SetCombatState();
}
}
public void AnimAttackCallback()
{
UpdateAim(targetToAim);
if (isRange)
{
weapon.CallShoot();
if (!attackClip.IsNull) RuntimeManager.PlayOneShot(attackClip, transform.position);
}
else
{
}
targetToAim = null;
isRange = false;
}
}