static private void ProcessRootMotionModifications(IAnimationRecordingState state, ref System.Collections.Generic.Dictionary <object, RootMotionModification> rootMotionModifications) { AnimationClip clip = state.activeAnimationClip; GameObject root = state.activeRootGameObject; Animator animator = root.GetComponent <Animator>(); bool isHuman = animator != null ? animator.isHuman : false; foreach (KeyValuePair <object, RootMotionModification> item in rootMotionModifications) { RootMotionModification m = item.Value; Transform target = item.Key as Transform; Vector3 scale = target.localScale * (isHuman ? animator.humanScale : 1); Vector3 position = target.localPosition; Quaternion rotation = target.localRotation; if (m.lastP.previousValue != null) { ProcessAnimatorModification(state, animator, m.px, "MotionT.x", position.x, scale.x); ProcessAnimatorModification(state, animator, m.py, "MotionT.y", position.y, scale.y); ProcessAnimatorModification(state, animator, m.pz, "MotionT.z", position.z, scale.z); } if (m.lastR.previousValue != null) { ProcessAnimatorModification(state, animator, m.rx, "MotionQ.x", rotation.x, 1); ProcessAnimatorModification(state, animator, m.ry, "MotionQ.y", rotation.y, 1); ProcessAnimatorModification(state, animator, m.rz, "MotionQ.z", rotation.z, 1); ProcessAnimatorModification(state, animator, m.rw, "MotionQ.w", rotation.w, 1); } } }
static private void ProcessAnimatorModifications(IAnimationRecordingState state, ref System.Collections.Generic.Dictionary <object, Vector3Modification> positionModifications, ref System.Collections.Generic.Dictionary <object, RotationModification> rotationModifications, ref System.Collections.Generic.Dictionary <object, Vector3Modification> scaleModifications) { System.Collections.Generic.Dictionary <object, RootMotionModification> rootMotionModifications = new Dictionary <object, RootMotionModification>(); AnimationClip clip = state.activeAnimationClip; GameObject root = state.activeRootGameObject; Animator animator = root.GetComponent <Animator>(); bool isHuman = animator != null ? animator.isHuman : false; bool hasRootMotion = animator != null ? animator.hasRootMotion : false; bool applyRootMotion = animator != null ? animator.applyRootMotion : false; // process animator positions List <object> discardListPos = new List <object>(); foreach (KeyValuePair <object, Vector3Modification> item in positionModifications) { Vector3Modification m = item.Value; Transform target = item.Key as Transform; if (target == null) { continue; } EditorCurveBinding binding = new EditorCurveBinding(); Type type = AnimationUtility.PropertyModificationToEditorCurveBinding(m.last.currentValue, state.activeRootGameObject, out binding); if (type == null) { continue; } bool isRootTransform = root.transform == target; bool isRootMotion = (isHuman || hasRootMotion || applyRootMotion) && isRootTransform; bool isHumanBone = isHuman && !isRootTransform && animator.IsBoneTransform(target); if (isHumanBone) { Debug.LogWarning("Keyframing translation on humanoid rig is not supported!", target as Transform); discardListPos.Add(item.Key); } else if (isRootMotion) { RootMotionModification rootMotionModification; if (!rootMotionModifications.TryGetValue(target, out rootMotionModification)) { rootMotionModification = new RootMotionModification(); rootMotionModifications[target] = rootMotionModification; } rootMotionModification.lastP = m.last; rootMotionModification.px = m.x; rootMotionModification.py = m.y; rootMotionModification.pz = m.z; discardListPos.Add(item.Key); } } foreach (object key in discardListPos) { positionModifications.Remove(key); } // process animator rotation List <object> discardListRot = new List <object>(); foreach (KeyValuePair <object, RotationModification> item in rotationModifications) { RotationModification m = item.Value; Transform target = item.Key as Transform; if (target == null) { continue; } EditorCurveBinding binding = new EditorCurveBinding(); Type type = AnimationUtility.PropertyModificationToEditorCurveBinding(m.lastQuatModification.currentValue, state.activeRootGameObject, out binding); if (type == null) { continue; } bool isRootTransform = root.transform == target; bool isRootMotion = (isHuman || hasRootMotion || applyRootMotion) && isRootTransform; bool isHumanBone = isHuman && !isRootTransform && animator.IsBoneTransform(target); if (isHumanBone) { Debug.LogWarning("Keyframing rotation on humanoid rig is not supported!", target as Transform); discardListRot.Add(item.Key); } else if (isRootMotion) { RootMotionModification rootMotionModification; if (!rootMotionModifications.TryGetValue(target, out rootMotionModification)) { rootMotionModification = new RootMotionModification(); rootMotionModifications[target] = rootMotionModification; } rootMotionModification.lastR = m.lastQuatModification; rootMotionModification.rx = m.x; rootMotionModification.ry = m.y; rootMotionModification.rz = m.z; rootMotionModification.rw = m.w; discardListRot.Add(item.Key); } } foreach (object key in discardListRot) { rotationModifications.Remove(key); } // process animator scales List <object> discardListScale = new List <object>(); foreach (KeyValuePair <object, Vector3Modification> item in scaleModifications) { Vector3Modification m = item.Value; Transform target = item.Key as Transform; if (target == null) { continue; } EditorCurveBinding binding = new EditorCurveBinding(); Type type = AnimationUtility.PropertyModificationToEditorCurveBinding(m.last.currentValue, state.activeRootGameObject, out binding); if (type == null) { continue; } bool isRootTransform = root.transform == target; bool isHumanBone = isHuman && !isRootTransform && animator.IsBoneTransform(target); if (isHumanBone) { Debug.LogWarning("Keyframing scale on humanoid rig is not supported!", target as Transform); discardListScale.Add(item.Key); } } foreach (object key in discardListScale) { scaleModifications.Remove(key); } ProcessRootMotionModifications(state, ref rootMotionModifications); }