110 lines
4.7 KiB
C#
110 lines
4.7 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor.Animations;
|
|
|
|
namespace CreatureControl {
|
|
|
|
public class CreatureAnimator : MonoBehaviour {
|
|
public Creature creature;
|
|
public RuntimeAnimatorController animatorController;
|
|
private Animator animator;
|
|
|
|
public enum RootMotionMode {
|
|
Normal,
|
|
Inverse
|
|
};
|
|
public RootMotionMode rootMotionMode = RootMotionMode.Normal;
|
|
|
|
[System.Serializable]
|
|
public class RootMotion {
|
|
public string clipName;
|
|
public Vector3 linearVelocity;
|
|
public Vector3 angularVelocity;
|
|
|
|
public readonly static RootMotion zero = new() {
|
|
linearVelocity = Vector3.zero,
|
|
angularVelocity = Vector3.zero
|
|
};
|
|
}
|
|
//public Dictionary<string, RootMotion> rootVelocities = new();
|
|
public List<RootMotion> rootVelocities = new();
|
|
public RootMotion GetRootMotion(string name) {
|
|
return this.rootVelocities.Find(rm => rm.clipName == name);
|
|
}
|
|
|
|
public Dictionary<Vector3, string> animationDirections = new();
|
|
|
|
|
|
protected virtual void Awake() {
|
|
this.creature = GetComponent<Creature>();
|
|
this.animator = creature.animator; // GetComponent<Animator>();
|
|
|
|
this.animator.applyRootMotion = this.rootMotionMode == RootMotionMode.Normal;
|
|
}
|
|
|
|
protected virtual void Update() {
|
|
if (rootMotionMode == RootMotionMode.Inverse) {
|
|
Vector3 speed = new(0, 0, 0.024f);
|
|
this.transform.localPosition += speed * Time.deltaTime; //0.0048f * Time.deltaTime * this.transform.forward;
|
|
InverseRootMotionUpdate();
|
|
}
|
|
else {
|
|
this.animator.SetFloat("Forward", 1f);
|
|
// Ensure that the pose of the model matches the target rig
|
|
this.creature.targetRig.transform.GetPositionAndRotation(out Vector3 targetRigPosition, out Quaternion targetRigOrientation);
|
|
this.creature.transform.SetPositionAndRotation(targetRigPosition, targetRigOrientation);
|
|
this.creature.targetRig.transform.SetPositionAndRotation(targetRigPosition, targetRigOrientation);
|
|
}
|
|
}
|
|
|
|
private Vector3 lastPosition;
|
|
protected void InverseRootMotionUpdate() {
|
|
if (lastPosition.sqrMagnitude > 0) {
|
|
Vector3 translation = this.transform.position - lastPosition;
|
|
Vector3 worldVelocity = translation / Time.deltaTime;
|
|
Vector3 localVelocity = transform.InverseTransformDirection(worldVelocity);
|
|
|
|
RootMotion rootMotion = this.GetRootMotion("AntWalkForward");
|
|
Vector3 animationVelocity = rootMotion.linearVelocity; // rootVelocities["AntWalkForward"].linearVelocity;
|
|
|
|
float fwdAnimationSpeed = localVelocity.z / animationVelocity.z;
|
|
this.animator.SetFloat("Forward", fwdAnimationSpeed);
|
|
}
|
|
lastPosition = this.transform.position;
|
|
}
|
|
|
|
void RetrieveBlendTreeAnimations(Animator animator, string parameterName, float targetValue) {
|
|
AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
|
|
// Check if the Animator Controller is valid
|
|
if (ac == null) {
|
|
Debug.LogError("Animator Controller is not set correctly.");
|
|
return;
|
|
}
|
|
|
|
// Iterate through each layer in the Animator Controller
|
|
foreach (AnimatorControllerLayer layer in ac.layers) {
|
|
// Access the state machine
|
|
foreach (ChildAnimatorState state in layer.stateMachine.states) {
|
|
// Check if the state contains a Blend Tree
|
|
if (state.state.motion is BlendTree blendTree) {
|
|
// Iterate through blend tree children
|
|
foreach (ChildMotion child in blendTree.children) {
|
|
if (child.directBlendParameter == parameterName) {
|
|
// Simulate parameter setting
|
|
//animator.SetFloat(parameterName, targetValue);
|
|
|
|
// Get the animation clip information
|
|
if (child.motion is AnimationClip clip) {
|
|
Debug.Log($"Animation Clip: {clip.name}, Speed: {child.timeScale}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
} |