You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Plugins/Animancer/Examples/09 Animator Controllers/02 3D Game Kit/States/IdleState.cs

96 lines
3.9 KiB
C#

2 months ago
// Animancer // Copyright 2020 Kybernetik //
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
using System;
using UnityEngine;
namespace Animancer.Examples.AnimatorControllers.GameKit
{
/// <summary>
/// A <see cref="CreatureState"/> which keeps the creature standing still.
/// </summary>
[AddComponentMenu(Strings.MenuPrefix + "Examples/Game Kit - Idle State")]
[HelpURL(Strings.APIDocumentationURL + ".Examples.AnimatorControllers.GameKit/IdleState")]
public sealed class IdleState : CreatureState
{
/************************************************************************************************************************/
[SerializeField] private ClipState.Transition _MainAnimation;
[SerializeField] private float _FirstRandomizeDelay = 5;
[SerializeField] private float _MinRandomizeInterval = 0;
[SerializeField] private float _MaxRandomizeInterval = 20;
[SerializeField] private ClipState.Transition[] _RandomAnimations;
private float _RandomizeTime;
// _RandomizeDelay was originally handled by the PlayerController (Idle Timeout).
// The min and max interval were handled by the RandomStateSMB on the Idle state in IdleSM.
/************************************************************************************************************************/
private void Awake()
{
Action onEnd = PlayMainAnimation;
for (int i = 0; i < _RandomAnimations.Length; i++)
{
_RandomAnimations[i].Events.Sequence.OnEnd = onEnd;
// We could just do `OnEnd = PlayMainAnimation` instead of declaring the delegate first, but that
// assignment is actually shorthand for `new Action(PlayMainAnimation)` which would create a new
// delegate object for each animation. This way all animations just share the same object.
}
}
/************************************************************************************************************************/
public override bool CanEnterState(CreatureState previousState)
{
return Creature.CharacterController.isGrounded;
}
/************************************************************************************************************************/
private void OnEnable()
{
PlayMainAnimation();
_RandomizeTime += _FirstRandomizeDelay;
}
private void PlayMainAnimation()
{
_RandomizeTime = UnityEngine.Random.Range(_MinRandomizeInterval, _MaxRandomizeInterval);
Creature.Animancer.Play(_MainAnimation);
}
/************************************************************************************************************************/
private void FixedUpdate()
{
if (Creature.CheckMotionState())
return;
Creature.UpdateSpeedControl();
// We use time where Mecanim used normalized time because choosing a number of seconds is much simpler than
// finding out how long the animation is and working with multiples of that value.
if (Creature.Animancer.States.Current == _MainAnimation.State &&
Creature.Animancer.States.Current.Time >= _RandomizeTime)
{
PlayRandomAnimation();
}
}
/************************************************************************************************************************/
private void PlayRandomAnimation()
{
var index = UnityEngine.Random.Range(0, _RandomAnimations.Length);
var animation = _RandomAnimations[index];
Creature.Animancer.Play(animation);
}
/************************************************************************************************************************/
}
}