BITFALL/Assets/Artists/Scripts/Player/PlayerAnimationController/PlayerAnimateStates.cs

425 lines
11 KiB
C#

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<Sprint>();
return;
case IPlayerRunState:
self.TransitionState<Run>();
return;
case IPlayerWalkState:
self.TransitionState<Walk>();
return;
case IPlayerCrouchState:
self.TransitionState<Crouch>();
return;
}
switch (entryState)
{
case IPlayerSprintState:
self.TransitionState<Sprint>();
return;
case IPlayerRunState:
self.TransitionState<Run>();
return;
case IPlayerWalkState:
self.TransitionState<Walk>();
return;
case IPlayerCrouchState:
self.TransitionState<Crouch>();
return;
default:
self.TransitionState<Walk>();
return;
}
}
}
[Serializable]
public class Walk : PlayerAnimateStates,IPlayerWalkState
{
[SerializeField] private MixerTransition2D mixer;
[SerializeField] private AnimationClip clip;
private MixerState<Vector2> state;
[Inject] private IHealth _health;
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<MixerState<Vector2>>();
var selfVelocity = self.Movement.Velocity;
selfVelocity = self.transform.InverseTransformDirection(selfVelocity);
var targetVelocity = new Vector2(selfVelocity.x, selfVelocity.z);
state.Parameter = Vector2.Lerp(
state.Parameter,
//new Vector2(v.x, v.z),
targetVelocity,
5*deltaTime
) ;
}
}
public override void OnMovementStateChanged(IEntityMovementState oldState, IEntityMovementState newState)
{
if (Enabled is false) return;
switch (newState)
{
case IPlayerRunState:
self.TransitionState<Run>();
return;
case IPlayerCrouchState:
self.TransitionState<Crouch>();
return;
case IPlayerSprintState:
self.TransitionState<Sprint>();
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<Walk>();
// break;
// case IPlayerCrouchState:
// self.TransitionState<Crouch>();
// break;
// }
}
}
[Serializable]
public class Crouch : PlayerAnimateStates,IPlayerCrouchState
{
[SerializeField] private MixerTransition2D mixer;
[SerializeField] private AnimationClip clip;
private MixerState<Vector2> 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<MixerState<Vector2>>();
var selfVelocity = self.Movement.Velocity;
selfVelocity = self.transform.InverseTransformDirection(selfVelocity);
var targetVelocity = new Vector2(selfVelocity.x, selfVelocity.z);
state.Parameter = Vector2.Lerp(
state.Parameter,
//new Vector2(v.x, v.z),
targetVelocity,
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<Walk>();
}
}
[Serializable]
public class Parachute : PlayerAnimateStates
{
[SerializeField] private AnimationClip clip;
[SerializeField] private AnimationClip exitClip;
[SerializeField] private MixerTransition2D _linearMixerTransition;
private MixerState<Vector2> 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<MixerState<Vector2>>();
}
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<Parachute>();
else if(Enabled && newState is not IPlayerKnockdownState)
{
self.TransitionState<Walk>();
}
}
}
[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<Slide>();
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<Vector2> 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;
var inputVector = (Vector2)_playerMovement.InputVector;
if (inputVector.magnitude is 0)
{
inputVector.y = self.Movement.AngularVelocity.y;
}
if (_playerMovement.AllowMovement && inputVector.magnitude > 0)
{
state = self.AnimancerComponent.Play(mixer,0.2f).As<MixerState<Vector2>>();
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<Knockdown>();
}
else if(Enabled)
{
self.TransitionState<Walk>();
}
}
}
[Serializable]
public class Link : PlayerAnimateStates,IPlayerLinkState
{
public int LinkArea { get; set; }
[SerializeField] private AnimationClip entryClip;
[SerializeField] private LinearMixerTransition mixer;
private MixerState<float> 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<MixerState<float>>();
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<Walk>();
break;
case IPlayerCrouchState:
self.TransitionState<Crouch>();
break;
case IPlayerSprintState:
self.TransitionState<Sprint>();
break;
}
}
else
{
if (newState is IPlayerLinkState linkState)
{
LinkArea = linkState.LinkArea;
self.TransitionState<Link>();
}
}
}
}
[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<Fixed>();
else if(Enabled)
Exit();
}
}
}