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