113 lines
No EOL
3.4 KiB
C#
113 lines
No EOL
3.4 KiB
C#
using R3;
|
|
using UnityEngine;
|
|
using KitsuneCafe.System;
|
|
using KitsuneCafe.Extension;
|
|
using KitsuneCafe.System.Attributes;
|
|
|
|
namespace KitsuneCafe.Entity
|
|
{
|
|
public class EntityAnimator : MonoBehaviour
|
|
{
|
|
private const float epsilon = 0.05f;
|
|
|
|
[SerializeField]
|
|
private Animator animator;
|
|
|
|
[SerializeField]
|
|
private new Rigidbody rigidbody;
|
|
|
|
[SerializeField]
|
|
private Motor motor;
|
|
|
|
[SerializeField]
|
|
private SprintFeature sprint;
|
|
|
|
[SerializeField, AnimatorParam("animator")]
|
|
private string movementSpeedParameter;
|
|
|
|
[SerializeField]
|
|
private float movementSmoothTime = 0.1f;
|
|
|
|
[SerializeField, AnimatorParam("animator")]
|
|
private string sprintingParameter;
|
|
|
|
[SerializeField, Range(0f, 1f)]
|
|
private float walkAnimationParamMax = 0.5f;
|
|
|
|
[SerializeField, Range(0f, 1f)]
|
|
private float sprintAnimationParamMax = 1.0f;
|
|
|
|
[SerializeField, AnimatorParam("animator")]
|
|
private string readyParam;
|
|
|
|
private void Reset()
|
|
{
|
|
animator = GetComponent<Animator>();
|
|
rigidbody = GetComponent<Rigidbody>();
|
|
motor = GetComponent<Motor>();
|
|
sprint = GetComponent<SprintFeature>();
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
var d = Disposable.CreateBuilder();
|
|
|
|
CurrentVelocity()
|
|
.Compose(CurrentAnimationSpeed)
|
|
.SmoothDamp(
|
|
() => animator.GetFloat(movementSpeedParameter),
|
|
movementSmoothTime,
|
|
UnityTimeProvider.FixedUpdate
|
|
)
|
|
.Subscribe(speed =>
|
|
{
|
|
animator.SetFloat(movementSpeedParameter, speed);
|
|
})
|
|
.AddTo(ref d);
|
|
|
|
sprint.IsSprinting
|
|
.DistinctUntilChanged()
|
|
.Subscribe(isSprinting =>
|
|
{
|
|
animator.SetBool(sprintingParameter, isSprinting);
|
|
})
|
|
.AddTo(ref d);
|
|
|
|
d.RegisterTo(destroyCancellationToken);
|
|
}
|
|
|
|
private Observable<float> CurrentVelocity()
|
|
{
|
|
return Observable.EveryUpdate(UnityFrameProvider.FixedUpdate)
|
|
.Select(_ => rigidbody.linearVelocity.sqrMagnitude)
|
|
.DistinctUntilChanged()
|
|
.Select(Mathf.Sqrt);
|
|
}
|
|
|
|
private Observable<float> CurrentAnimationSpeed(Observable<float> speedSource)
|
|
{
|
|
var scaleFactor = motor.MaxSpeedSource.Select(maxSpeed => NormalizationFactor(maxSpeed, motor.DefaultMaxSpeed));
|
|
|
|
return speedSource
|
|
.CombineLatest(motor.MaxSpeedSource, scaleFactor, NormalizeSpeed)
|
|
.DistinctUntilChanged(FEqualityComparer<float>.Create(KMath.IsApproxEqual));
|
|
}
|
|
|
|
private float NormalizationFactor(float maxSpeed, float defaultMaxSpeed)
|
|
{
|
|
return maxSpeed > defaultMaxSpeed ? sprintAnimationParamMax : walkAnimationParamMax;
|
|
}
|
|
|
|
private float NormalizeSpeed(float currentSpeed, float maxSpeed, float factor)
|
|
{
|
|
if (currentSpeed > maxSpeed && maxSpeed > epsilon)
|
|
{
|
|
return factor;
|
|
}
|
|
else
|
|
{
|
|
return Mathf.InverseLerp(0, maxSpeed, currentSpeed) * factor;
|
|
}
|
|
}
|
|
}
|
|
} |