private List <AnimationWindowKeyframe> GetKeys(PropertyModification[] modifications) { var keys = new List <AnimationWindowKeyframe>(); EditorCurveBinding[] bindings = AnimationWindowUtility.PropertyModificationsToEditorCurveBindings(modifications, state.activeRootGameObject, state.activeAnimationClip); if (bindings.Length == 0) { return(keys); } for (int i = 0; i < state.allCurves.Count; ++i) { AnimationWindowCurve curve = state.allCurves[i]; if (Array.Exists(bindings, binding => curve.binding.Equals(binding))) { int keyIndex = curve.GetKeyframeIndex(state.time); if (keyIndex >= 0) { keys.Add(curve.m_Keyframes[keyIndex]); } } } return(keys); }
static void AddRotationKey(IAnimationRecordingState state, EditorCurveBinding binding, Type type, Vector3 previousEulerAngles, Vector3 currentEulerAngles) { AnimationClip clip = state.activeAnimationClip; if ((clip.hideFlags & HideFlags.NotEditable) != 0) { return; } EditorCurveBinding[] additionalBindings = RotationCurveInterpolation.RemapAnimationBindingForRotationAddKey(binding, clip); // Add key at current frame for (int i = 0; i < 3; i++) { AnimationWindowCurve curve = new AnimationWindowCurve(clip, additionalBindings[i], type); if (state.addZeroFrame) { // Is it a new curve? if (curve.length == 0) { if (state.currentFrame != 0) { AnimationWindowUtility.AddKeyframeToCurve(curve, previousEulerAngles[i], type, AnimationKeyTime.Frame(0, clip.frameRate)); } } } AnimationWindowUtility.AddKeyframeToCurve(curve, currentEulerAngles[i], type, AnimationKeyTime.Frame(state.currentFrame, clip.frameRate)); state.SaveCurve(curve); } }
public void ProcessCandidates() { BeginKeyModification(); EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(m_CandidateClip); EditorCurveBinding[] objectCurveBindings = AnimationUtility.GetObjectReferenceCurveBindings(m_CandidateClip); List <AnimationWindowCurve> curves = new List <AnimationWindowCurve>(); for (int i = 0; i < state.allCurves.Count; ++i) { AnimationWindowCurve curve = state.allCurves[i]; EditorCurveBinding remappedBinding = UnityEditor.Enemeteen.RotationCurveInterpolation.RemapAnimationBindingForRotationCurves(curve.binding, m_CandidateClip); if (Array.Exists(bindings, binding => remappedBinding.Equals(binding)) || Array.Exists(objectCurveBindings, binding => remappedBinding.Equals(binding))) { curves.Add(curve); } } AnimationWindowUtility.AddKeyframes(state, curves, time); EndKeyModification(); ClearCandidates(); }
public void GoToNextKeyframe(PropertyModification[] modifications) { EditorCurveBinding[] bindings = AnimationWindowUtility.PropertyModificationsToEditorCurveBindings(modifications, state.activeRootGameObject, state.activeAnimationClip); if (bindings.Length == 0) { return; } List <AnimationWindowCurve> curves = new List <AnimationWindowCurve>(); for (int i = 0; i < state.allCurves.Count; ++i) { AnimationWindowCurve curve = state.allCurves[i]; if (Array.Exists(bindings, binding => curve.binding.Equals(binding))) { curves.Add(curve); } } float newTime = AnimationWindowUtility.GetNextKeyframeTime(curves.ToArray(), time.time, state.clipFrameRate); SetCurrentTime(state.SnapToFrame(newTime, AnimationWindowState.SnapMode.SnapToClipFrame)); state.Repaint(); }
private void FillPropertyGroup(ref EditorCurveBinding?[] propertyGroup, EditorCurveBinding lastBinding, string propertyGroupName, ref List <AnimationWindowCurve> curvesCache) { var newBinding = lastBinding; newBinding.isPhantom = true; if (!propertyGroup[0].HasValue) { newBinding.propertyName = propertyGroupName + ".x"; AnimationWindowCurve curve = new AnimationWindowCurve(animationClip, newBinding, GetEditorCurveValueType(newBinding)); curve.selectionBinding = this; curvesCache.Add(curve); } if (!propertyGroup[1].HasValue) { newBinding.propertyName = propertyGroupName + ".y"; AnimationWindowCurve curve = new AnimationWindowCurve(animationClip, newBinding, GetEditorCurveValueType(newBinding)); curve.selectionBinding = this; curvesCache.Add(curve); } if (!propertyGroup[2].HasValue) { newBinding.propertyName = propertyGroupName + ".z"; AnimationWindowCurve curve = new AnimationWindowCurve(animationClip, newBinding, GetEditorCurveValueType(newBinding)); curve.selectionBinding = this; curvesCache.Add(curve); } }
static void AddKey(IAnimationRecordingState state, EditorCurveBinding binding, Type type, object previousValue, object currentValue) { GameObject root = state.activeRootGameObject; AnimationClip clip = state.activeAnimationClip; if ((clip.hideFlags & HideFlags.NotEditable) != 0) { return; } AnimationWindowCurve curve = new AnimationWindowCurve(clip, binding, type); // Add previous value at first frame on empty curves. if (state.addZeroFrame) { // Is it a new curve? if (curve.length == 0) { if (state.currentFrame != 0) { AnimationWindowUtility.AddKeyframeToCurve(curve, previousValue, type, AnimationKeyTime.Frame(0, clip.frameRate)); } } } // Add key at current frame. AnimationWindowUtility.AddKeyframeToCurve(curve, currentValue, type, AnimationKeyTime.Frame(state.currentFrame, clip.frameRate)); state.SaveCurve(curve); }
// Retrieve current value. If bindings are available and value is animated, use bindings to get value. // Otherwise, evaluate AnimationWindowCurve at current time. public static object GetCurrentValue(AnimationWindowState state, AnimationWindowCurve curve) { if (state.previewing && curve.rootGameObject != null) { return(AnimationWindowUtility.GetCurrentValue(curve.rootGameObject, curve.binding)); } else { return(curve.Evaluate(state.currentTime)); } }
public AnimationWindowKeyframe(AnimationWindowCurve curve, Keyframe key) { this.time = key.time; this.value = key.value; this.curve = curve; this.m_InTangent = key.inTangent; this.m_OutTangent = key.outTangent; this.m_InWeight = key.inWeight; this.m_OutWeight = key.outWeight; this.m_WeightedMode = key.weightedMode; this.m_TangentMode = key.tangentModeInternal; this.m_curve = curve; }
static void ProcessRootMotionModification(IAnimationRecordingState state, Animator animator, UndoPropertyModification modification, string name, float value, float scale) { AnimationClip clip = state.activeAnimationClip; if ((clip.hideFlags & HideFlags.NotEditable) != 0) { return; } float prevValue = value; object oValue; if (ValueFromPropertyModification(modification.currentValue, new EditorCurveBinding(), out oValue)) { value = (float)oValue; } if (ValueFromPropertyModification(modification.previousValue, new EditorCurveBinding(), out oValue)) { prevValue = (float)oValue; } value = Mathf.Abs(scale) > Mathf.Epsilon ? value / scale : value; prevValue = Mathf.Abs(scale) > Mathf.Epsilon ? prevValue / scale : prevValue; var binding = new EditorCurveBinding(); binding.propertyName = name; binding.path = ""; binding.type = typeof(Animator); var prop = new PropertyModification(); prop.target = animator; prop.propertyPath = binding.propertyName; prop.value = value.ToString(CultureInfo.InvariantCulture.NumberFormat); state.AddPropertyModification(binding, prop, modification.keepPrefabOverride); AnimationWindowCurve curve = new AnimationWindowCurve(clip, binding, typeof(float)); if (state.addZeroFrame && state.currentFrame != 0 && curve.length == 0) { AnimationWindowUtility.AddKeyframeToCurve(curve, prevValue, typeof(float), AnimationKeyTime.Frame(0, clip.frameRate)); } AnimationWindowUtility.AddKeyframeToCurve(curve, value, typeof(float), AnimationKeyTime.Frame(state.currentFrame, clip.frameRate)); state.SaveCurve(curve); }
private AnimationWindowHierarchyPropertyNode AddPropertyToHierarchy(AnimationWindowCurve curve, AnimationWindowHierarchyNode parentNode) { AnimationWindowHierarchyPropertyNode node = new AnimationWindowHierarchyPropertyNode(curve.type, 0, curve.propertyName, curve.path, parentNode, curve.binding, curve.isPPtrCurve); if (parentNode.icon != null) { node.icon = parentNode.icon; } else { node.icon = GetIcon(curve.binding); } node.indent = curve.depth; node.curves = new[] { curve }; return(node); }
public List <AnimationWindowHierarchyNode> CreateTreeFromCurves() { List <AnimationWindowHierarchyNode> nodes = new List <AnimationWindowHierarchyNode>(); List <AnimationWindowCurve> singlePropertyCurves = new List <AnimationWindowCurve>(); AnimationWindowCurve[] curves = state.allCurves.ToArray(); AnimationWindowHierarchyNode parentNode = (AnimationWindowHierarchyNode)m_RootItem; for (int i = 0; i < curves.Length; i++) { AnimationWindowCurve curve = curves[i]; if (!state.ShouldShowCurve(curve)) { continue; } AnimationWindowCurve nextCurve = i < curves.Length - 1 ? curves[i + 1] : null; singlePropertyCurves.Add(curve); bool areSameGroup = nextCurve != null && AnimationWindowUtility.GetPropertyGroupName(nextCurve.propertyName) == AnimationWindowUtility.GetPropertyGroupName(curve.propertyName); bool areSamePathAndType = nextCurve != null && curve.path.Equals(nextCurve.path) && curve.type == nextCurve.type; // We expect curveBindings to come sorted by propertyname // So we compare curve vs nextCurve. If its different path or different group (think "scale.xyz" as group), then we know this is the last element of such group. if (i == curves.Length - 1 || !areSameGroup || !areSamePathAndType) { if (singlePropertyCurves.Count > 1) { nodes.Add(AddPropertyGroupToHierarchy(singlePropertyCurves.ToArray(), parentNode)); } else { nodes.Add(AddPropertyToHierarchy(singlePropertyCurves[0], parentNode)); } singlePropertyCurves.Clear(); } } return(nodes); }
public void SaveCurve(AnimationWindowCurve curve) { Undo.RegisterCompleteObjectUndo(curve.clip, "Edit Candidate Curve"); AnimationWindowUtility.SaveCurve(curve.clip, curve); }
public void SaveCurve(AnimationWindowCurve curve) { m_State.SaveCurve(curve.clip, curve); }
private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row) { bool curvesChanged = false; if (node is AnimationWindowHierarchyPropertyNode) { AnimationWindowCurve[] curves = node.curves; if (curves == null || curves.Length == 0) { return; } // We do valuefields for dopelines that only have single curve AnimationWindowCurve curve = curves[0]; object objectValue = CurveBindingUtility.GetCurrentValue(state, curve); if (objectValue is float) { float value = (float)objectValue; Rect valueFieldDragRect = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide - k_ValueFieldDragWidth, rect.y, k_ValueFieldDragWidth, rect.height); Rect valueFieldRect = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide, rect.y, k_ValueFieldWidth, rect.height); if (Event.current.type == EventType.MouseMove && valueFieldRect.Contains(Event.current.mousePosition)) { s_WasInsideValueRectFrame = Time.frameCount; } EditorGUI.BeginChangeCheck(); if (curve.valueType == typeof(bool)) { value = GUI.Toggle(valueFieldRect, m_HierarchyItemValueControlIDs[row], value != 0, GUIContent.none, EditorStyles.toggle) ? 1 : 0; } else { int id = m_HierarchyItemValueControlIDs[row]; bool enterInTextField = (EditorGUIUtility.keyboardControl == id && EditorGUIUtility.editingTextField && Event.current.type == EventType.KeyDown && (Event.current.character == '\n' || (int)Event.current.character == 3)); // Force back keyboard focus to float field editor when editing it. // TreeView forces keyboard focus on itself at mouse down and we lose focus here. if (EditorGUI.s_RecycledEditor.controlID == id && Event.current.type == EventType.MouseDown && valueFieldRect.Contains(Event.current.mousePosition)) { GUIUtility.keyboardControl = id; } value = EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, valueFieldRect, valueFieldDragRect, id, value, "g5", m_AnimationSelectionTextField, true); if (enterInTextField) { GUI.changed = true; Event.current.Use(); } } if (float.IsInfinity(value) || float.IsNaN(value)) { value = 0; } if (EditorGUI.EndChangeCheck()) { string undoLabel = "Edit Key"; AnimationKeyTime newAnimationKeyTime = AnimationKeyTime.Time(state.currentTime, curve.clip.frameRate); AnimationWindowKeyframe existingKeyframe = null; foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes) { if (Mathf.Approximately(keyframe.time, state.currentTime)) { existingKeyframe = keyframe; } } if (existingKeyframe == null) { AnimationWindowUtility.AddKeyframeToCurve(curve, value, curve.valueType, newAnimationKeyTime); } else { existingKeyframe.value = value; } state.SaveCurve(curve.clip, curve, undoLabel); curvesChanged = true; } } } if (curvesChanged) { state.ResampleAnimation(); } }
public AnimationWindowKeyframe(AnimationWindowCurve curve, ObjectReferenceKeyframe key) { this.time = key.time; this.value = key.value; this.curve = curve; }