// Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
using Animancer.Examples.StateMachines;
using Animancer.Units;
using UnityEngine;
namespace Animancer.Examples.AnimatorControllers
{
///
/// A which moves the character according to their
/// .
///
///
///
/// This class is very similar to , except that it manages a
/// Blend Tree instead of a Mixer.
///
///
/// Hybrid Character
///
/// https://kybernetik.com.au/animancer/api/Animancer.Examples.AnimatorControllers/HybridMoveState
///
[AddComponentMenu(Strings.ExamplesMenuPrefix + "Hybrid - Move State")]
[HelpURL(Strings.DocsURLs.ExampleAPIDocumentation + nameof(AnimatorControllers) + "/" + nameof(HybridMoveState))]
public sealed class HybridMoveState : CharacterState
{
/************************************************************************************************************************/
[SerializeField, DegreesPerSecond] private float _TurnSpeed = 360;
[SerializeField] private float _ParameterFadeSpeed = 2;
private float _MoveBlend;
/************************************************************************************************************************/
///
/// Normally the class would have a reference to the specific type of
/// we want, but for the sake of reusing code from the earlier example, we
/// just use a type cast here.
///
private HybridAnimancerComponent HybridAnimancer
=> (HybridAnimancerComponent)Character.Animancer;
/************************************************************************************************************************/
private void OnEnable()
{
HybridAnimancer.PlayController();
HybridAnimancer.SetBool(Animations.IsMoving, true);
_MoveBlend = Character.Parameters.WantsToRun ? 1 : 0;
}
/************************************************************************************************************************/
private void Update()
{
UpdateAnimation();
UpdateTurning();
}
/************************************************************************************************************************/
/// This method is similar to .
private void UpdateAnimation()
{
var target = Character.Parameters.WantsToRun ? 1 : 0;
_MoveBlend = Mathf.MoveTowards(
_MoveBlend,
target,
_ParameterFadeSpeed * Time.deltaTime);
HybridAnimancer.SetFloat(Animations.MoveBlend, _MoveBlend);
}
/************************************************************************************************************************/
/// This method is identical to .
private void UpdateTurning()
{
var movement = Character.Parameters.MovementDirection;
if (movement == default)
return;
var targetAngle = Mathf.Atan2(movement.x, movement.z) * Mathf.Rad2Deg;
var turnDelta = _TurnSpeed * Time.deltaTime;
var transform = Character.Animancer.transform;
var eulerAngles = transform.eulerAngles;
eulerAngles.y = Mathf.MoveTowardsAngle(eulerAngles.y, targetAngle, turnDelta);
transform.eulerAngles = eulerAngles;
}
/************************************************************************************************************************/
}
}