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