using System; using System.Collections.Generic; using UnityEngine; namespace UnityEditor.Animations.Rigging { /// /// Utility class that provides an easy way of retrieving EditorCurveBindings for common data types. /// public static class EditorCurveBindingUtils { /// /// Collects EditorCurveBindings for a Vector3 on a MonoBehavior. /// /// The Type of the MonoBehavior the Vector3 is found on. /// The root to which the bindings are relative. Generally the root has the Animator which animates the Vector3. /// The MonoBehavior on which the Vector3 is found. /// Name of the Vector3 variable we are constructing a binding for. /// List to which the bindings for the Vector3 will be appended. public static void CollectVector3Bindings(Transform root, T component, string propertyName, List bindings) where T : MonoBehaviour { if (root == null || component == null || propertyName == "" || bindings == null) throw new ArgumentNullException("Arguments cannot be null."); var path = AnimationUtility.CalculateTransformPath(component.transform, root); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(T), propertyName + ".x")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(T), propertyName + ".y")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(T), propertyName + ".z")); } /// /// Collects translation, rotation and scale bindings for a Transform component. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the Transform. /// The transform whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectTRSBindings(Transform root, Transform transform, List bindings) { CollectPositionBindings(root, transform, bindings); CollectRotationBindings(root, transform, bindings); CollectScaleBindings(root, transform, bindings); } /// /// Collects translation, rotation bindings for a Transform component. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the Transform. /// The transform whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectTRBindings(Transform root, Transform transform, List bindings) { CollectPositionBindings(root, transform, bindings); CollectRotationBindings(root, transform, bindings); } /// /// Collects translation bindings for a Transform component. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the Transform. /// The transform whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectPositionBindings(Transform root, Transform transform, List bindings) { if (root == null || transform == null || bindings == null) throw new ArgumentNullException("Arguments cannot be null."); var path = AnimationUtility.CalculateTransformPath(transform, root); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.x")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.y")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.z")); } /// /// Collects rotation bindings for a Transform component. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the Transform. /// The transform whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectRotationBindings(Transform root, Transform transform, List bindings) { if (root == null || transform == null || bindings == null) throw new ArgumentNullException("Arguments cannot be null."); var path = AnimationUtility.CalculateTransformPath(transform, root); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "localEulerAnglesRaw.x")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "localEulerAnglesRaw.y")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "localEulerAnglesRaw.z")); } /// /// Collects scale bindings for a Transform component. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the Transform. /// The transform whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectScaleBindings(Transform root, Transform transform, List bindings) { if (root == null || transform == null || bindings == null) throw new ArgumentNullException("Arguments cannot be null."); var path = AnimationUtility.CalculateTransformPath(transform, root); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalScale.x")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalScale.y")); bindings.Add(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalScale.z")); } /// /// Collects the binding for a single float property on a MonoBehavior. /// /// The root to which the bindings are relative. Generally the root has the Animator which animates the float property. /// The component on which the property is found. /// The name of the float property whose bindings are collected. /// List to which the bindings for the Transform will be appended. public static void CollectPropertyBindings(Transform root, MonoBehaviour component, string propertyName, List bindings) { if (root == null || component == null || bindings == null) throw new ArgumentNullException("Arguments cannot be null."); var path = AnimationUtility.CalculateTransformPath(component.transform, root); bindings.Add(EditorCurveBinding.FloatCurve(path, component.GetType(), propertyName)); } internal static bool RemapRotationBinding(AnimationClip clip, EditorCurveBinding binding, ref EditorCurveBinding rotationBinding) { if (!binding.propertyName.StartsWith("localEulerAngles")) return false; string suffix = binding.propertyName.Split('.')[1]; rotationBinding = binding; // Euler Angles rotationBinding.propertyName = "localEulerAnglesRaw." + suffix; if (AnimationUtility.GetEditorCurve(clip, rotationBinding) != null) return true; // Euler Angles (Quaternion) interpolation rotationBinding.propertyName = "localEulerAnglesBaked." + suffix; if (AnimationUtility.GetEditorCurve(clip, rotationBinding) != null) return true; // Quaternion interpolation rotationBinding.propertyName = "localEulerAngles." + suffix; if (AnimationUtility.GetEditorCurve(clip, rotationBinding) != null) return true; return false; } } }