101 lines
3.0 KiB
C#
101 lines
3.0 KiB
C#
using UnityEngine;
|
|
|
|
namespace OctoCore.Components
|
|
{
|
|
public class OctoCharacterAnimation : MonoBehaviour
|
|
{
|
|
[SerializeField] private Animator animator;
|
|
[SerializeField] private float walkSpeed = 8;
|
|
[SerializeField] private float runSpeed = 15;
|
|
[SerializeField, Range(1, 10)] private int sampling = 5;
|
|
|
|
private bool backward;
|
|
private float backwardSmooth;
|
|
private float sideSmooth;
|
|
private float smoothSpeed;
|
|
private Vector4[] positions;
|
|
private Vector3 lastStep;
|
|
private Vector3 direction;
|
|
|
|
private float step = .1f;
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
Gizmos.color = Color.cyan;
|
|
Gizmos.DrawRay(transform.position + Vector3.up, transform.forward);
|
|
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawRay(transform.position + Vector3.up, direction);
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
positions = new Vector4[sampling + 1];
|
|
for (int i = 0; i < sampling; i++)
|
|
{
|
|
positions[i] = transform.position;
|
|
positions[i].z = .002f;
|
|
}
|
|
|
|
direction = transform.forward;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (lastStep != transform.position && Vector3.Distance(lastStep, transform.position) > step)
|
|
{
|
|
Vector3 offset = (lastStep - transform.position).normalized * step;
|
|
lastStep = transform.position + offset;
|
|
}
|
|
|
|
direction = Vector3.Lerp(direction, (transform.position - lastStep).normalized, Time.deltaTime * 10);
|
|
|
|
float speed = GetSpeed();
|
|
smoothSpeed = Mathf.Lerp(smoothSpeed, speed, Time.deltaTime * 10);
|
|
|
|
float move = Mathf.Clamp01(smoothSpeed / walkSpeed);
|
|
float run = Mathf.Clamp01((smoothSpeed - walkSpeed) / (runSpeed - walkSpeed));
|
|
|
|
float dot = Vector3.Dot(transform.forward, direction.normalized);
|
|
Vector3 crs = Vector3.Cross(transform.forward, direction.normalized);
|
|
|
|
backward = dot < 0;
|
|
backwardSmooth = Mathf.Lerp(backwardSmooth, backward ? 1 : 0, Time.deltaTime * 10);
|
|
|
|
sideSmooth = Mathf.Lerp(sideSmooth, (1 - Mathf.Abs(dot)) * Mathf.Sign(transform.InverseTransformDirection(crs).y) * direction.magnitude, Time.deltaTime * 20);
|
|
|
|
run *= 1 - backwardSmooth;
|
|
run *= 1 - Mathf.Abs(sideSmooth);
|
|
|
|
//Debug.Log(dot);
|
|
|
|
animator.SetFloat("move", Mathf.Sqrt(move));
|
|
animator.SetFloat("run", run);
|
|
animator.SetFloat("backward", backwardSmooth);
|
|
animator.SetFloat("side", sideSmooth);
|
|
}
|
|
|
|
float GetSpeed()
|
|
{
|
|
float offset = 0;
|
|
float delta = 0;
|
|
|
|
for (int i = 0; i < positions.Length - 1; i++)
|
|
{
|
|
offset += Vector3.Distance(positions[i], positions[i + 1]);
|
|
delta += positions[i].w;
|
|
}
|
|
|
|
for (int i = positions.Length - 1; i > 0; i--)
|
|
positions[i] = positions[i - 1];
|
|
|
|
positions[0] = transform.position;
|
|
positions[0].w = Time.deltaTime;
|
|
|
|
if (offset > 0 && delta > 0)
|
|
return offset / (delta / 3.6f);
|
|
else return 0;
|
|
}
|
|
}
|
|
|
|
} |