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); }
public void AddKeyframe(AnimationWindowKeyframe key, AnimationKeyTime keyTime) { // If there is already key in this time, we always want to remove it RemoveKeyframe(keyTime); m_Keyframes.Add(key); m_Keyframes.Sort((a, b) => a.time.CompareTo(b.time)); }
public static AnimationKeyTime Frame(int frame, float frameRate) { AnimationKeyTime key = new AnimationKeyTime(); key.m_Frame = (frame < 0) ? 0 : frame; key.m_Time = key.m_Frame / frameRate; key.m_FrameRate = frameRate; return(key); }
public static AnimationKeyTime Time(float time, float frameRate) { AnimationKeyTime key = new AnimationKeyTime(); key.m_Time = Mathf.Max(time, 0f); key.m_FrameRate = frameRate; key.m_Frame = UnityEngine.Mathf.RoundToInt(key.m_Time * frameRate); return(key); }
public void SetCurrentTime(float value) { if (!Mathf.Approximately(value, time.time)) { m_Time = AnimationKeyTime.Time(value, state.frameRate); StartPreview(); ClearCandidates(); ResampleAnimation(); } }
public void SetCurrentFrame(int value) { if (value != time.frame) { m_Time = AnimationKeyTime.Frame(value, state.frameRate); StartPreview(); ClearCandidates(); ResampleAnimation(); } }
public int GetKeyframeIndex(AnimationKeyTime time) { for (int i = 0; i < m_Keyframes.Count; i++) { if (time.ContainsTime(m_Keyframes[i].time)) { return(i); } } return(-1); }
public void RemoveKeyframe(AnimationKeyTime time) { // Loop backwards so key removals don't mess up order for (int i = m_Keyframes.Count - 1; i >= 0; i--) { if (time.ContainsTime(m_Keyframes[i].time)) { m_Keyframes.RemoveAt(i); } } }
public AnimationWindowKeyframe FindKeyAtTime(AnimationKeyTime keyTime) { int index = GetKeyframeIndex(keyTime); if (index == -1) { return(null); } return(m_Keyframes[index]); }
public void OnSelectionChanged() { // Set back time at beginning and stop recording. if (state != null) { m_Time = AnimationKeyTime.Time(0f, state.frameRate); } StopPreview(); StopPlayback(); }
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); }
public bool playFromBeginning = false; // TO DO public bool PlaybackUpdate() { if (!playing) { return(false); } float deltaTime = Time.realtimeSinceStartup - m_PreviousUpdateTime; m_PreviousUpdateTime = Time.realtimeSinceStartup; deltaTime *= playbackSpeed; float newTime = time.time + deltaTime; if (loop) { if (newTime > state.maxTime) { newTime = state.minTime; } else if (newTime < state.minTime) { newTime = state.maxTime; } } else { if (newTime > state.maxTime) { newTime = state.maxTime; StopPlayback(); } else if (newTime < state.minTime) { newTime = state.minTime; StopPlayback(); } } m_Time = AnimationKeyTime.Time(Mathf.Clamp(newTime, state.minTime, state.maxTime), state.frameRate); ResampleAnimation(); return(true); }
public bool StartPlayback() { if (!canPlay) { return(false); } if (!playing) { AnimationMode.StartAnimationPlaybackMode(); m_PreviousUpdateTime = Time.realtimeSinceStartup; // Auto-Preview when start playing StartPreview(); ClearCandidates(); } if (playFromBeginning) { if (playbackSpeed > 0) { m_Time = AnimationKeyTime.Time(state.minTime, state.frameRate); } else { m_Time = AnimationKeyTime.Time(state.maxTime, state.frameRate); } } else { if (!loop) { if (time.time >= state.maxTime && playbackSpeed > 0) { m_Time = AnimationKeyTime.Time(state.minTime, state.frameRate); } else if (time.time <= state.minTime && playbackSpeed < 0) { m_Time = AnimationKeyTime.Time(state.maxTime, state.frameRate); } } } return(true); }
public bool HasKeyframe(AnimationKeyTime time) { return(GetKeyframeIndex(time) != -1); }
public bool Equals(AnimationKeyTime key) { return(m_Frame == key.m_Frame && m_FrameRate == key.m_FrameRate && Mathf.Approximately(m_Time, key.m_Time)); }
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(); } }
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); } }