425 lines
11 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|