115 lines
3.5 KiB
C#

using Characters.Enemy.States;
using Koptilnya.StateMachine;
using Mirror;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
namespace Characters.Enemy
{
public class Enemy : Pawn
{
public NavMeshAgent agent;
public Animator animator;
public Rig aimRig;
public AudioSource audioSource;
public ParticleSystem hitVFX;
public Transform aimTransform;
public float aggressionDistance = 5f;
[HideInInspector] public bool canAttack;
[SyncVar(hook = nameof(OnStateChanged))] public EnemyState state = EnemyState.Idle;
[SyncVar, HideInInspector] public float aimRigWeight;
public readonly StateMachine<EnemyState> stateMachine = new StateMachine<EnemyState>();
public Transform target;
public NetworkAnimator networkAnimator;
private CustomNetworkManager _networkManager;
private NetworkGameManager _networkGameManager;
private float _targetAimRigWeight;
private float _stepCycle;
private AudioClip _footstepClip;
private const float StepDelay = 0.15f;
private const float RunSpeed = 4.974f;
private static readonly int SpeedAnimHash = Animator.StringToHash("speed");
void Start()
{
_networkManager = NetworkManager.singleton.GetComponent<CustomNetworkManager>();
_networkGameManager = NetworkGameManager.singleton;
networkAnimator = GetComponent<NetworkAnimator>();
_footstepClip = Resources.Load<AudioClip>("Audio/EnemySounds/Steps/monsterStep1");
stateMachine.Add(new IdleState(this));
stateMachine.Add(new PatrolState(this));
stateMachine.Add(new ChaseState(this));
stateMachine.Add(new StunnedState(this));
stateMachine.SetCurrentState(state);
}
void Update()
{
Footsteps();
stateMachine.Update();
agent.speed = _speedMul * RunSpeed;
aimRigWeight = isServer ? Mathf.Lerp(aimRigWeight, _targetAimRigWeight, Time.deltaTime) : aimRigWeight;
aimRig.weight = aimRigWeight;
animator.SetFloat(SpeedAnimHash, agent.velocity.magnitude);
}
void FixedUpdate()
{
stateMachine.FixedUpdate();
}
public void SetAimRigWeight(float value)
{
_targetAimRigWeight = value;
}
void Footsteps()
{
// float velocity = ((_position - transform.position) / Time.deltaTime).magnitude;
float velocity = 0;
float clampedVelocity = Mathf.Clamp(RunSpeed / velocity + 1, 1, RunSpeed);
if (Time.time > _stepCycle && velocity > 0)
{
audioSource.pitch = 1f + Random.Range(-0.1f, 0.1f);
audioSource.PlayOneShot(_footstepClip);
_stepCycle = Time.time + (clampedVelocity * StepDelay);
}
}
public override void TakeDamage()
{
base.TakeDamage();
if (state == EnemyState.Stunned)
{
stateMachine.GetCurrentState().ReEnter();
}
else
{
state = EnemyState.Stunned;
}
}
void OnStateChanged(EnemyState _, EnemyState newState)
{
Debug.Log($"{_} -> {newState}");
stateMachine.SetCurrentState(newState);
}
}
}