// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik // #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value. using UnityEngine; namespace Animancer.Samples.AnimatorControllers { /// /// Implements the same behaviour as /// using a . /// /// /// /// Sample: /// /// Hybrid Character /// /// /// https://kybernetik.com.au/animancer/api/Animancer.Samples.AnimatorControllers/HybridCharacterAnimations /// [AddComponentMenu(Strings.SamplesMenuPrefix + "Animator Controllers - Hybrid Character Animations")] [AnimancerHelpUrl(typeof(HybridCharacterAnimations))] // Awake before Animancer to disable the OptionalWarnings before it triggers them. [DefaultExecutionOrder(AnimancerComponent.DefaultExecutionOrder - 1000)] public class HybridCharacterAnimations : MonoBehaviour { /************************************************************************************************************************/ public static readonly int IsMovingParameter = Animator.StringToHash("IsMoving"); [SerializeField] private HybridAnimancerComponent _Animancer; [SerializeField] private ClipTransition _Action; private State _CurrentState; private enum State { NotActing,// Idle and Move can be interrupted. Acting,// Action can only be interrupted by itself. } /************************************************************************************************************************/ protected virtual void Awake() { _Action.Events.OnEnd = UpdateMovement; // This sample's documentation explains why these warnings exist so we don't need them enabled. OptionalWarning.NativeControllerHumanoid.Disable(); OptionalWarning.NativeControllerHybrid.Disable(); } /************************************************************************************************************************/ protected virtual void Update() { switch (_CurrentState) { case State.NotActing: UpdateMovement(); UpdateAction(); break; case State.Acting: UpdateAction(); break; } } /************************************************************************************************************************/ private void UpdateMovement() { _CurrentState = State.NotActing; float forward = SampleInput.WASD.y; bool isMoving = forward > 0; // This sample script demonstrates both the Native and Hybrid approaches. // In a real project you would only use one system or the other, not both. // Native - Animator Controller assigned to the Animator. // In this case, the HybridAnimancerComponent is unnecessary and you should use a base AnimancerComponent. if (_Animancer.Animator.runtimeAnimatorController != null) { if (_Animancer.Controller.Controller != null) { _Animancer.Controller.Controller = null; Debug.LogWarning( $"A Native Animator Controller is assigned to the Animator component" + $" and a Hybrid Animator Controller is also assigned to the {nameof(HybridAnimancerComponent)}." + $" That's not necessarily a problem, but using both systems at the same time is very unusual.", this); } // Return to the Animator Controller by fading out Animancer's layers. AnimancerLayer layer = _Animancer.Layers[0]; if (layer.TargetWeight > 0) layer.StartFade(0, 0.25f); // Set parameters on the Animator compponent. _Animancer.Animator.SetBool(IsMovingParameter, isMoving); } // Hybrid - Animator Controller assigned to the HybridAnimancerComponent. // In this case, the Animator component doesn't have a reference to the Animator Controller. else if (_Animancer.Controller.Controller != null) { // Return to the Animator Controller by playing the ControllerTransition. _Animancer.PlayController(); // Set parameters on the ControllerState. _Animancer.SetBool(IsMovingParameter, isMoving); } else { Debug.LogError("No Animator Controller is assigned.", this); } } /************************************************************************************************************************/ private void UpdateAction() { if (SampleInput.LeftMouseUp) { _CurrentState = State.Acting; _Animancer.Play(_Action); } } /************************************************************************************************************************/ } }