public static void DrawStateData(AnimationPlayer animationPlayer, int selectedLayer, PersistedInt selectedState, AnimationPlayerEditor currentEditor) { ReloadCheck(); var markDirty = false; var layer = animationPlayer.layers[selectedLayer]; if (layer.states.Count == 0) { EditorGUILayout.LabelField("No states"); return; } if (!layer.states.IsInBounds(selectedState)) { Debug.LogError($"Out of bounds state: {selectedState} out of {layer.states.Count} states! Resetting to 0"); selectedState.SetTo(0); return; } var stateName = layer.states[selectedState].Name; EditorGUILayout.LabelField($"Settings for \"{stateName}\":"); EditorGUI.indentLevel++; DrawStateData(layer.states[selectedState], ref markDirty); GUILayout.Space(20f); EditorGUILayout.BeginHorizontal(); if (selectedState == 0) { EditorGUILayout.LabelField("This is the default state of this layer", GUILayout.Width(250f)); } else if (GUILayout.Button("Set as the default state of this layer", GUILayout.Width(250f))) { layer.states.Swap(selectedState, 0); selectedState.SetTo(0); markDirty = true; } GUILayout.FlexibleSpace(); var deleteThisState = EditorUtilities.AreYouSureButton($"Delete {stateName}", "Are you sure", $"DeleteState_{selectedState}_{selectedLayer}", 1f); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; GUILayout.Space(20f); currentEditor.previewer.DrawStatePreview(selectedLayer, selectedState); if (deleteThisState) { DeleteState(animationPlayer, layer, selectedState); markDirty = true; } if (markDirty) { currentEditor.MarkDirty(); } }
private static void DrawSequence(Sequence state, ref bool markDirty) { var oldLoopMode = state.loopMode; state.loopMode = (SequenceLoopMode)EditorGUILayout.EnumPopup("Loop Mode", state.loopMode); if (state.loopMode != oldLoopMode) { markDirty = true; } if (state.loopMode == SequenceLoopMode.DontLoop) { EditorGUILayout.HelpBox("The clips in the sequence are played one by one. The final one will loop if it's set to loop (but won't get any animation events after the first time it plays).", MessageType.None); } else { EditorGUILayout.HelpBox("The clips in the sequence are played one by one, looping after the last one is finished", MessageType.None); } EditorGUILayout.LabelField("Sequence"); EditorGUI.indentLevel++; var toRemove = -1; var old = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 60f; for (var i = 0; i < state.clips.Count; i++) { var oldClip = state.clips[i]; using (new EditorGUILayout.HorizontalScope()) { state.clips[i] = EditorUtilities.ObjectField("Clip", oldClip); if (GUILayout.Button("-", GUILayout.Width(20f))) { toRemove = i; } } if (state.clips[i] != oldClip) { state.OnClipAssigned(state.clips[i]); markDirty = true; } } EditorGUIUtility.labelWidth = old; EditorGUI.indentLevel--; EditorGUI.indentLevel--; GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add new part", GUILayout.Width(150f))) { state.clips.Add(null); markDirty = true; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (toRemove != -1) { state.clips.RemoveAt(toRemove); markDirty = true; } }
private static void Draw1DBlendTree(BlendTree1D state, ref bool markDirty) { state.blendVariable = EditorUtilities.TextField("Blend with variable", state.blendVariable, 130f); EditorGUI.indentLevel++; int swapIndex = -1; if (state.blendTree == null) { state.blendTree = new System.Collections.Generic.List <BlendTreeEntry1D>(); } for (var i = 0; i < state.blendTree.Count; i++) { var blendTreeEntry = state.blendTree[i]; var whenLabel = $"When '{state.blendVariable}' ="; var whenLabelRequiredWidth = GUI.skin.label.CalcSize(new GUIContent(whenLabel)).x; var remainingAfterClipLabel = Screen.width - 30f - 70f - 25f - 100f; var remainingAfterWhenLabel = Screen.width - whenLabelRequiredWidth - 70f - 25f - 100f; EditorGUILayout.BeginHorizontal(); { var oldClip = blendTreeEntry.clip; blendTreeEntry.clip = EditorUtilities.ObjectField("Clip", blendTreeEntry.clip, 30f, remainingAfterClipLabel); if (blendTreeEntry.clip != oldClip) { if (blendTreeEntry.clip != null) { state.OnClipAssigned(blendTreeEntry.clip); } markDirty = true; } EditorGUI.BeginDisabledGroup(i == 0); if (GUILayout.Button("\u2191", upDownButtonStyle, upDownButtonOptions)) { swapIndex = i; } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { blendTreeEntry.threshold = EditorUtilities.FloatField(whenLabel, blendTreeEntry.threshold, whenLabelRequiredWidth, remainingAfterWhenLabel); EditorGUI.BeginDisabledGroup(i == state.blendTree.Count - 1); if (GUILayout.Button("\u2193", upDownButtonStyle, upDownButtonOptions)) { swapIndex = i + 1; } EditorGUI.EndDisabledGroup(); // Remove 1D blend tree entry if (GUILayout.Button("Remove", GUILayout.Width(70f))) { state.blendTree.RemoveAt(i); } } EditorGUILayout.EndHorizontal(); if (i != state.blendTree.Count - 1) { EditorUtilities.Splitter(width: Screen.width - 100f); } } if (swapIndex != -1) { markDirty = true; state.blendTree.Swap(swapIndex, swapIndex - 1); } EditorGUI.indentLevel--; GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add blend tree entry", GUILayout.Width(150f))) { state.blendTree.Add(new BlendTreeEntry1D()); markDirty = true; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); }
private static void Draw2DBlendTree(BlendTree2D state, ref bool markDirty) { state.blendVariable = EditorUtilities.TextField("First blend variable", state.blendVariable, 120f); state.blendVariable2 = EditorUtilities.TextField("Second blend variable", state.blendVariable2, 120f); EditorGUI.indentLevel++; if (state.blendTree == null) { state.blendTree = new System.Collections.Generic.List <BlendTreeEntry2D>(); } int swapIndex = -1; for (var i = 0; i < state.blendTree.Count; i++) { var blendTreeEntry = state.blendTree[i]; var oldClip = blendTreeEntry.clip; blendTreeEntry.clip = EditorUtilities.ObjectField("Clip", blendTreeEntry.clip, 150f, 200f); if (blendTreeEntry.clip != oldClip && blendTreeEntry.clip != null) { markDirty |= state.OnClipAssigned(blendTreeEntry.clip); } EditorGUILayout.BeginHorizontal(); { blendTreeEntry.threshold1 = EditorUtilities.FloatField($"When '{state.blendVariable}' =", blendTreeEntry.threshold1, 150f, 200f); EditorGUI.BeginDisabledGroup(i == 0); if (GUILayout.Button("\u2191", upDownButtonStyle, upDownButtonOptions)) { swapIndex = i; } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); { blendTreeEntry.threshold2 = EditorUtilities.FloatField($"When '{state.blendVariable2}' =", blendTreeEntry.threshold2, 150f, 200f); EditorGUI.BeginDisabledGroup(i == state.blendTree.Count - 1); if (GUILayout.Button("\u2193", upDownButtonStyle, upDownButtonOptions)) { swapIndex = i + 1; } EditorGUI.EndDisabledGroup(); // Remove 2D blend tree entry if (GUILayout.Button("Remove", GUILayout.Width(70f))) { state.blendTree.RemoveAt(i); } } EditorGUILayout.EndHorizontal(); if (i != state.blendTree.Count - 1) { EditorUtilities.Splitter(width: 350f); } } if (swapIndex != -1) { markDirty = true; state.blendTree.Swap(swapIndex, swapIndex - 1); } EditorGUI.indentLevel--; GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add blend tree entry", GUILayout.Width(150f))) { state.blendTree.Add(new BlendTreeEntry2D()); markDirty = true; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); }
private void DrawAnimationStatePreview() { EditorUtilities.Splitter(); var oldPreviewMode = previewMode; EditorUtilities.DrawHorizontal(() => { EditorGUILayout.LabelField("Preview mode"); EditorGUI.BeginDisabledGroup(previewMode == PreviewMode.Automatic); if (GUILayout.Button("Automatic")) { previewMode = PreviewMode.Automatic; } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(previewMode == PreviewMode.Manual); if (GUILayout.Button("Manual")) { previewMode = PreviewMode.Manual; } EditorGUI.EndDisabledGroup(); }); if (oldPreviewMode == PreviewMode.Manual && previewMode == PreviewMode.Automatic) { automaticPreviewLastTime = Time.realtimeSinceStartup; } if (previewMode == PreviewMode.Manual) { var oldPreviewTime = previewTime; previewTime = EditorGUILayout.Slider(previewTime, 0f, currentPreviewedState.Duration); previewGraph.Evaluate(previewTime - oldPreviewTime); } else { var currentTime = Time.realtimeSinceStartup; var deltaTime = currentTime - automaticPreviewLastTime; automaticPreviewLastTime = currentTime; previewTime = (previewTime + deltaTime) % currentPreviewedState.Duration; previewGraph.Evaluate(deltaTime); var oldVal = previewTime; previewTime = EditorGUILayout.Slider(previewTime, 0f, currentPreviewedState.Duration); if (oldVal != previewTime) { previewMode = PreviewMode.Manual; } } SceneView.RepaintAll(); if (GUILayout.Button("Stop preview")) { StopPreviewing(); } }
public static void DrawStateData(AnimationPlayer animationPlayer, PersistedInt selectedLayer, PersistedInt selectedState, AnimationPlayerEditor currentEditor) { if (reloadChecker == null) { reloadChecker = new object(); upDownButtonOptions = new[] { GUILayout.Width(25f), GUILayout.Height(15f) }; upDownButtonStyle = new GUIStyle(GUI.skin.button) { alignment = TextAnchor.UpperCenter, clipping = TextClipping.Overflow }; } var markDirty = false; var layer = animationPlayer.layers[selectedLayer]; if (layer.states.Count == 0) { EditorGUILayout.LabelField("No states"); return; } if (!layer.states.IsInBounds(selectedState)) { Debug.LogError($"Out of bounds state: {selectedState} out of {layer.states.Count} states! Resetting to 0"); selectedState.SetTo(0); return; } var stateName = layer.states[selectedState].Name; EditorGUILayout.LabelField($"Settings for \"{stateName}\":"); EditorGUI.indentLevel++; DrawStateData(layer.states[selectedState], ref markDirty); GUILayout.Space(20f); EditorGUILayout.BeginHorizontal(); if (selectedState == 0) { EditorGUILayout.LabelField("This is the default state of this layer", GUILayout.Width(250f)); } else if (GUILayout.Button("Set as the default state of this layer", GUILayout.Width(250f))) { layer.states.Swap(selectedState, 0); selectedState.SetTo(0); markDirty = true; } GUILayout.FlexibleSpace(); var deleteThisState = EditorUtilities.AreYouSureButton($"Delete {stateName}", "Are you sure", $"DeleteState_{selectedState}_{selectedLayer}", 1f); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; if (deleteThisState) { DeleteState(animationPlayer, layer, selectedState); markDirty = true; } if (markDirty) { currentEditor.MarkDirty(); } GUILayout.Space(20f); currentEditor.previewer.DrawStatePreview(selectedLayer, selectedState); }
private static void DrawStateData(AnimationState state, ref bool updateStateNames) { const float labelWidth = 55f; var old = state.Name; state.Name = EditorUtilities.TextField("Name", state.Name, labelWidth); if (old != state.Name) { updateStateNames = true; } state.speed = EditorUtilities.DoubleField("Speed", state.speed, labelWidth); //@TODO: Use pattern matching when C# 7 var type = state.GetType(); if (type == typeof(SingleClipState)) { var singleClipState = (SingleClipState)state; var oldClip = singleClipState.clip; singleClipState.clip = EditorUtilities.ObjectField("Clip", singleClipState.clip, labelWidth); if (singleClipState.clip != null && singleClipState.clip != oldClip) { updateStateNames |= singleClipState.OnClipAssigned(singleClipState.clip); } } else if (type == typeof(BlendTree1D)) { var blendTree = (BlendTree1D)state; blendTree.blendVariable = EditorUtilities.TextField("Blend with variable", blendTree.blendVariable, 120f); EditorGUI.indentLevel++; foreach (var blendTreeEntry in blendTree.blendTree) { updateStateNames |= DrawBlendTreeEntry(state, blendTreeEntry, blendTree.blendVariable); } EditorGUI.indentLevel--; GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add blend tree entry", GUILayout.Width(150f))) { blendTree.blendTree.Add(new BlendTreeEntry1D()); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } else if (type == typeof(BlendTree2D)) { var blendTree2D = (BlendTree2D)state; blendTree2D.blendVariable = EditorUtilities.TextField("First blend variable", blendTree2D.blendVariable, 120f); blendTree2D.blendVariable2 = EditorUtilities.TextField("Second blend variable", blendTree2D.blendVariable2, 120f); EditorGUI.indentLevel++; foreach (var blendTreeEntry in blendTree2D.blendTree) { updateStateNames |= DrawBlendTreeEntry(state, blendTreeEntry, blendTree2D.blendVariable, blendTree2D.blendVariable2); } EditorGUI.indentLevel--; GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add blend tree entry", GUILayout.Width(150f))) { blendTree2D.blendTree.Add(new BlendTreeEntry2D()); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.LabelField($"Unknown animation state type: {type.Name}"); } }
private static void DrawThresholdsFor2DBlendTree(string blendVarName1, string blendVarName2, BlendTreeEntry2D as2D) { as2D.threshold1 = EditorUtilities.FloatField($"When '{blendVarName1}' =", as2D.threshold1, 150f, 200f); as2D.threshold2 = EditorUtilities.FloatField($"When '{blendVarName2}' =", as2D.threshold2, 150f, 200f); }
private static void DrawThresholdFor1DBlendTree(string blendVarName, BlendTreeEntry1D entry) { entry.threshold = EditorUtilities.FloatField($"When '{blendVarName}' =", entry.threshold, 150f, 200f); }