179 lines
4.7 KiB
C#
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;
|
|
}
|
|
|
|
|
|
}
|