I have a slightly, a little more complicated set up for may animations for the targeting.
I also have my State Machine set up slightly different, I have a Hierarchical State Machine, when adding in the Animations for the targeting state I just had to add the Move X and Move Y for the Animator, the state machine was already taking care of the Idle, Walk, Run portion.
Targeting State
public class CombatPlayerTargetingState : CombatAndTraversalBaseState
{
private static readonly int TargetingBlendTreeHash = Animator.StringToHash("TargetingBlendTree");
private static readonly int MoveSpeedXHash = Animator.StringToHash("MoveSpeedX");
private static readonly int MoveSpeedYHash = Animator.StringToHash("MoveSpeedY");
public CombatPlayerTargetingState(CombatAndTraversalStateMachine context, CombatAndTraversalStateFactory factory)
: base(context, factory) {}
#region State Implementation
public override void EnterState()
{
Context.WalkMultiplier = Context.TargetWalkMultiplier;
Context.RunMultiplier = Context.TargetRunMultiplier;
Context.Animator.Play(TargetingBlendTreeHash);
InitializeSubState();
}
protected override void UpdateState()
{
if(CheckSwitchStates()) return;
Context.Animator.SetFloat(MoveSpeedXHash, Context.MovementInput.x);
Context.Animator.SetFloat(MoveSpeedYHash, Context.MovementInput.y);
}
protected override void ExitState() {}
protected override void InitializeSubState()
{
switch (Context.IsMovementPressed)
{
case true when Context.IsRunPressed:
SetSubState(Factory.Run);
break;
case true when !Context.IsRunPressed:
SetSubState(Factory.Walk);
break;
default:
SetSubState(Factory.Idle);
break;
}
}
#endregion
#region State<CombatAndTraversalBaseState, CombatAndTraversalStateFactory, CombatAndTraversalStateMachine> Implementation
public override bool CheckSwitchStates()
{
if (!Context.Targeter.CurrentTarget)
{
SwitchState(Factory.FreeLook);
return true;
}
if (Context.IsTargeting) return false;
Context.Targeter.Cancel();
SwitchState(Factory.FreeLook);
return true;
}
#endregion
}
Run State
public class FreeLook : CombatAndTraversalBaseState
{
private static readonly int FreeLookBlendTreeHash = Animator.StringToHash("FreeLookBlendTree");
public FreeLook(CombatAndTraversalStateMachine context, CombatAndTraversalStateFactory factory)
: base(context, factory) {}
#region State Implementation
public override void EnterState()
{
Context.WalkMultiplier = Context.FreeLookWalkMultiplier;
Context.RunMultiplier = Context.FreeLookRunMultiplier;
Context.Animator.Play(FreeLookBlendTreeHash);
InitializeSubState();
}
protected override void UpdateState()
{
if(CheckSwitchStates()) return;
}
protected override void ExitState() {}
protected override void InitializeSubState()
{
switch (Context.IsMovementPressed)
{
case true when Context.IsRunPressed:
SetSubState(Factory.Run);
break;
case true when !Context.IsRunPressed:
SetSubState(Factory.Walk);
break;
default:
SetSubState(Factory.Idle);
break;
}
}
#endregion
#region State<CombatAndTraversalBaseState, CombatAndTraversalStateFactory, CombatAndTraversalStateMachine> Implementation
public override bool CheckSwitchStates()
{
if (!Context.IsTargeting) return false;
if (Context.Targeter && !Context.Targeter.SelectTarget()) return false;
SwitchState(Factory.Target);
return true;
}
#endregion
}
Walk State the Idle and Run are set up Similar, The difference being setting the Move Speed on the Animator, setting the applied Movement, and the Check Switch States.
public class CombatPlayerWalkState : CombatAndTraversalBaseState
{
private Vector2 _inputMovement;
public CombatPlayerWalkState(CombatAndTraversalStateMachine context, CombatAndTraversalStateFactory factory)
: base(context, factory) {}
#region State Implementation
public override void EnterState()
{
Context.Animator.SetFloat(CombatAndTraversalStateMachine.MoveSpeedHash, 0.5f);
}
protected override void UpdateState()
{
if(CheckSwitchStates()) return;
_inputMovement = Context.MovementInput.normalized;
Context.AppliedMovementX = _inputMovement.x * Context.WalkMultiplier;
Context.AppliedMovementZ = _inputMovement.y * Context.WalkMultiplier;
}
protected override void ExitState() {}
protected override void InitializeSubState() {}
#endregion
#region State<CombatAndTraversalBaseState, CombatAndTraversalStateFactory, CombatAndTraversalStateMachine> Implementation
public override bool CheckSwitchStates()
{
switch (Context.IsMovementPressed)
{
case false:
SwitchState(Factory.Idle);
return true;
case true when Context.IsRunPressed:
SwitchState(Factory.Run);
return true;
}
return false;
}
#endregion
}