135 lines
5.5 KiB
C#
135 lines
5.5 KiB
C#
// 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
|
|
{
|
|
/// <summary>
|
|
/// Implements the same behaviour as <see cref="BasicCharacterAnimations"/>
|
|
/// using a <see cref="HybridAnimancerComponent"/>.
|
|
/// </summary>
|
|
///
|
|
/// <remarks>
|
|
/// <strong>Sample:</strong>
|
|
/// <see href="https://kybernetik.com.au/animancer/docs/samples/animator-controllers/character">
|
|
/// Hybrid Character</see>
|
|
/// </remarks>
|
|
///
|
|
/// 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);
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
}
|
|
}
|