// 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; } /************************************************************************************************************************/ } }