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