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 rootVelocities = new(); public List rootVelocities = new(); public RootMotion GetRootMotion(string name) { return this.rootVelocities.Find(rm => rm.clipName == name); } public Dictionary animationDirections = new(); protected virtual void Awake() { this.creature = GetComponent(); this.animator = creature.animator; // GetComponent(); 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}"); } } } } } } } } }