using System; using System.Collections; using System.Collections.Generic; using Animancer; using BITFALL.Player.Movement; using BITKit; using BITKit.Entities; using BITKit.StateMachine; using UnityEngine; using UnityEngine.Animations.Rigging; using Cysharp.Threading.Tasks; // ReSharper disable UnassignedField.Global namespace BITFALL.Player.Animation.States { public abstract class PlayerAnimateStates : IPlayerAnimationState { public virtual bool Enabled { get; set; } protected IPlayerAnimationState entryState; [Inject] public PlayerAnimationController self; public virtual void Initialize() { } public virtual void OnStateEntry(IState old) { entryState = old as IPlayerAnimationState; } public virtual void OnStateUpdate(float deltaTime) { } public virtual void OnStateExit(IState old, IState newState) { } public virtual void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { } protected void Exit() { if (Enabled is false) return; switch (self._movement.CurrentState) { case IPlayerSprintState: self.TransitionState(); return; case IPlayerRunState: self.TransitionState(); return; case IPlayerWalkState: self.TransitionState(); return; case IPlayerCrouchState: self.TransitionState(); return; } switch (entryState) { case IPlayerSprintState: self.TransitionState(); return; case IPlayerRunState: self.TransitionState(); return; case IPlayerWalkState: self.TransitionState(); return; case IPlayerCrouchState: self.TransitionState(); return; default: self.TransitionState(); return; } } } [Serializable] public class Walk : PlayerAnimateStates,IPlayerWalkState { [SerializeField] private MixerTransition2D mixer; [SerializeField] private AnimationClip clip; private MixerState state; [Inject] private IHealth _health; // public override void OnStateEntry(IState old) // { // base.OnStateEntry(old); // state = self.AnimancerComponent.Play(mixer).As>(); // var v = self._movement.LocomotionBasedVelocity; // state.Parameter = new Vector2(v.x, v.z); // } public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if (_health.IsAlive is false) return; var v = self._movement.LocomotionBasedVelocity; if (v.magnitude <= 0.1f) { self.AnimancerComponent.Play(clip, 0.2f); } else { state = self.AnimancerComponent.Play(mixer).As>(); state.Parameter = Vector2.Lerp( state.Parameter,new Vector2(v.x, v.z),5*deltaTime ) ; } } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); //aimRig.weight = 0; } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if (Enabled is false) return; switch (newState) { case IPlayerRunState: self.TransitionState(); return; case IPlayerCrouchState: self.TransitionState(); return; case IPlayerSprintState: self.TransitionState(); return; } } } [Serializable] public class Run : PlayerAnimateStates,IPlayerRunState { [SerializeField] private AnimationClip clip; public override void OnStateEntry(IState old) { base.OnStateEntry(old); self.AnimancerComponent.Play(clip); } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if(Enabled &&newState is not IPlayerRunState)Exit(); } } [Serializable] public class Sprint : PlayerAnimateStates,IPlayerSprintState { [SerializeField] private AnimationClip clip; public override void OnStateEntry(IState old) { //self.animator.Play(BITConstant.Player.Sprint); self.AnimancerComponent.Play(clip); } public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if(self._movement.CurrentState is not IPlayerSprintState) Exit(); } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { //if(Enabled &&newState is not IPlayerSprintState)Exit(); // if (Enabled is false) return; // switch (newState) // { // case IPlayerWalkState: // self.TransitionState(); // break; // case IPlayerCrouchState: // self.TransitionState(); // break; // } } } [Serializable] public class Crouch : PlayerAnimateStates,IPlayerCrouchState { [SerializeField] private MixerTransition2D mixer; [SerializeField] private AnimationClip clip; private MixerState state; public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if (self._movement.Velocity.magnitude > 0.1f) { var v = self._movement.LocomotionBasedVelocity; state = self.AnimancerComponent.Play(mixer,0.2f).As>(); state.Parameter = Vector2.Lerp( state.Parameter, new Vector2(v.x, v.z), 5 * deltaTime ); } else { self.AnimancerComponent.Play(clip,0.2f); } } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if (Enabled is false) return; if(newState is not IPlayerCrouchState) self.TransitionState(); } } [Serializable] public class Parachute : PlayerAnimateStates { [SerializeField] private AnimationClip clip; [SerializeField] private AnimationClip exitClip; [SerializeField] private MixerTransition2D _linearMixerTransition; private MixerState state; [Inject] private IEntityOverride _entityOverride; public override async void OnStateEntry(IState old) { //_entityOverride.AddOverride(this); await self.AnimancerComponent.Play(clip); if (!Enabled) return; //entityOverride.RemoveOverride(this); state = self.AnimancerComponent.Play(_linearMixerTransition).As>(); } public override async void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); state = null; if (self._movement.CurrentState is IPlayerWalkState && self._movement.IsGrounded) { _entityOverride.AddOverride(this); var x = self.AnimancerComponent.Layers[1].Play(exitClip, 0.1f); await x; x.Stop(); } _entityOverride.RemoveOverride(this); } public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if (state is not null) { var velocity = self._movement.LocomotionBasedVelocity; state.Parameter = new Vector2(velocity.x,velocity.z); } } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if(newState is IPlayerParachuteState) self.TransitionState(); else if(Enabled && newState is not IPlayerKnockdownState) { self.TransitionState(); } } } [Serializable] public class Slide : PlayerAnimateStates { [SerializeField] private AnimationClip clip; public override void OnStateEntry(IState old) { //self.animator.Play(BITConstant.Player.Slide); self.AnimancerComponent.Play(clip); } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if(newState is IPlayerSlideState) self.TransitionState(); else if(Enabled && newState is not IPlayerKnockdownState) { Exit(); } } } [Serializable] public class Knockdown : PlayerAnimateStates { [SerializeField] private AnimationClip entryClip; [SerializeField] private AnimationClip clip; [SerializeField] private MixerTransition2D mixer; private MixerState state; [Inject] private IEntityOverride _entityOverride; [Inject] private IPlayerMovement _playerMovement; public override void Initialize() { base.Initialize(); //_initialController = self.animator.animator.runtimeAnimatorController; } public override async void OnStateEntry(IState old) { _entityOverride.AddOverride(this); await self.AnimancerComponent.Play(entryClip,0.1f); _entityOverride.RemoveOverride(this); } public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if (_entityOverride.IsOvering) return; if (((Vector2)_playerMovement.InputVector).magnitude > 0) { state = self.AnimancerComponent.Play(mixer,0.2f).As>(); state.Parameter = Vector2.Lerp( state.Parameter, _playerMovement.InputVector, 3 * deltaTime ); } else { self.AnimancerComponent.Play(clip,0.2f); } } public override void OnStateExit(IState old, IState newState) { _entityOverride.RemoveOverride(this); } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if (newState is IPlayerKnockdownState) { self.TransitionState(); } else if(Enabled) { self.TransitionState(); } } } [Serializable] public class Link : PlayerAnimateStates,IPlayerLinkState { public int LinkArea { get; set; } [SerializeField] private AnimationClip entryClip; [SerializeField] private LinearMixerTransition mixer; private MixerState state; [Inject] private IPlayerMovement _playerMovement; public override async void OnStateEntry(IState old) { switch (LinkArea) { case 5: await self.AnimancerComponent.Play(entryClip); if (!Enabled) return; state = self.AnimancerComponent.Play(mixer).As>(); break; } } public override void OnStateExit(IState old, IState newState) { base.OnStateExit(old, newState); state = null; } public override void OnStateUpdate(float deltaTime) { base.OnStateUpdate(deltaTime); if (state is not null) { state.Parameter = Mathf.Lerp(state.Parameter, _playerMovement.InputVector.y, 5 * deltaTime); } } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { if (Enabled) { switch (newState) { case IPlayerWalkState: self.TransitionState(); break; case IPlayerCrouchState: self.TransitionState(); break; case IPlayerSprintState: self.TransitionState(); break; } } else { if (newState is IPlayerLinkState linkState) { LinkArea = linkState.LinkArea; self.TransitionState(); } } } } [Serializable] public sealed class Fixed : PlayerAnimateStates { public override void OnStateEntry(IState old) { } public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState) { base.OnMovementStateChanged(oldState, newState); if(newState is IPlayerFixedState) self.TransitionState(); else if(Enabled) Exit(); } } }