private void DrawRuntimeDebugData() { if (!Application.isPlaying) { return; } EditorGUILayout.LabelField("Current blend variable values:"); var blendVars = animationPlayer.GetBlendVariables(); EditorUtilities.DrawIndented(() => { foreach (var blendVar in blendVars) { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.LabelField(blendVar, GUILayout.Width(100f)); EditorGUILayout.LabelField(animationPlayer.GetBlendVar(blendVar).ToString()); } EditorGUILayout.EndHorizontal(); } }); EditorUtilities.Splitter(); if (!animationPlayer.gameObject.scene.IsValid()) { //is looking at the prefab at runtime, don't attempt to draw the graph! return; } for (int i = 0; i < animationPlayer.GetStateCount(selectedLayer); i++) { EditorGUILayout.BeginHorizontal(); { string stateName = animationPlayer.layers[selectedLayer].states[i].Name; if (GUILayout.Button($"Blend to {stateName} using default transition")) { animationPlayer.Play(i, selectedLayer); } if (GUILayout.Button($"Blend to {stateName} over .5 secs")) { animationPlayer.Play(i, TransitionData.Linear(.5f), selectedLayer); } if (GUILayout.Button($"Snap to {stateName}")) { animationPlayer.SnapTo(i, selectedLayer); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.LabelField("Playing clip " + animationPlayer.GetPlayingState(selectedLayer)); for (int i = animationPlayer.GetStateCount(selectedLayer) - 1; i >= 0; i--) { EditorGUILayout.LabelField("Current weigth for state " + i + ": " + animationPlayer.GetStateWeight(i, selectedLayer)); } }
private static void DrawCreateNewTransition(AnimationPlayer animationPlayer, Action <StateTransition> SetSelectedTransition, string[] stateNamesInLayer, string fromStateName, string toStateName, AnimationPlayerState selectedState, AnimationLayer layer) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (GUILayout.Button($"Create new transition from {fromStateName}")) { GenericMenu menu = new GenericMenu(); foreach (var state in stateNamesInLayer) { menu.AddItem(new GUIContent($"Transition from {fromStateName} to {state}"), false, () => { //@TODO: If this is the first transition between the states, it should be set as default. EditorUtilities.RecordUndo(animationPlayer, $"Adding transition from {fromStateName} to {toStateName}"); var newState = new StateTransition { FromState = selectedState, ToState = layer.states.Find(s => s.Name == state), transitionData = TransitionData.Linear(.2f) }; layer.transitions.Add(newState); SetSelectedTransition(newState); }); } menu.ShowAsContext(); } } }
public static void DrawTransitions(AnimationPlayer animationPlayer, PersistedInt selectedLayer, PersistedInt selectedStateIdx, PersistedInt selectedToStateIdx, string[] stateNamesInLayer) { var layer = animationPlayer.layers[selectedLayer]; if (layer.states.Count == 0) { EditorGUILayout.LabelField("No states, can't define transitions"); return; } var selectedState = layer.states[selectedStateIdx]; var selectedToState = layer.states[selectedToStateIdx]; var selectedTransition = layer.transitions.Find(t => t.FromState == selectedState && t.ToState == selectedToState); var fromStateName = selectedState.Name; var toStateName = selectedToState.Name; if (selectedTransition != null) { EditorGUILayout.LabelField($"Selected transition: From \"{fromStateName}\" to \"{toStateName}\""); EditorUtilities.RecordUndo(animationPlayer, $"Edit of transition from {fromStateName} to {toStateName}"); EditorUtilities.DrawIndented(() => { selectedTransition.transitionData = DrawTransitionData(selectedTransition.transitionData); GUILayout.Space(20f); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (EditorUtilities.AreYouSureButton("Clear transition", "Are you sure?", "Clear_Transition_" + fromStateName + "_" + toStateName, 1f, GUILayout.Width(150f))) { EditorUtilities.RecordUndo(animationPlayer, $"Clear transition from {fromStateName} to {toStateName}"); layer.transitions.Remove(selectedTransition); } EditorGUILayout.EndHorizontal(); }); } EditorUtilities.Splitter(); var transitionsFromState = layer.transitions.Where(t => t.FromState == selectedState).ToList(); if (transitionsFromState.Count == 0) { EditorGUILayout.LabelField($"No defined transitions from {fromStateName}"); } else { EditorGUILayout.LabelField($"Transitions from {fromStateName}:"); EditorGUILayout.Space(); EditorUtilities.DrawHorizontal(() => { GUILayout.FlexibleSpace(); EditorUtilities.DrawVertical(() => { EditorUtilities.DrawIndented(() => { foreach (var transition in transitionsFromState) { EditorGUI.BeginDisabledGroup(transition == selectedTransition); if (GUILayout.Button(transition.ToState.Name, GUILayout.MinWidth(100f))) { selectedToStateIdx.SetTo(layer.states.IndexOf(transition.ToState)); } EditorGUI.EndDisabledGroup(); } }); }); }); } EditorGUILayout.Space(); EditorUtilities.DrawHorizontal(() => { GUILayout.FlexibleSpace(); if (GUILayout.Button("Create new transition")) { GenericMenu menu = new GenericMenu(); foreach (var state in stateNamesInLayer) { menu.AddItem(new GUIContent($"Transition from {fromStateName} to {state}"), false, () => { EditorUtilities.RecordUndo(animationPlayer, $"Adding transition from {fromStateName} to {toStateName}"); var newState = new StateTransition { FromState = selectedState, ToState = layer.states.Find(s => s.Name == state), transitionData = TransitionData.Linear(.2f) }; layer.transitions.Add(newState); selectedToStateIdx.SetTo(layer.states.FindIndex(s => s.Name == state)); }); } menu.ShowAsContext(); } }); }
private void HandleInitialization(bool isGUICall) { if (scriptReloadChecker == null) { // Unity persists some objects through reload, and fails to persist others. This makes it hard to figure out if // something needs to be re-cached. This solves that - we know that Unity can't persist a raw object, so if it's null, a reload is neccessary. scriptReloadChecker = new object(); metaDataDrawer = new MetaDataDrawer(animationPlayer); stylesCreated = false; transitionsNeedsUpdate = true; MarkDirty(); } if (isGUICall && !stylesCreated) { var backgroundTex = EditorUtilities.MakeTex(1, 1, new Color(1.0f, 1.0f, 1.0f, .1f)); editLayerStyle = new GUIStyle { normal = { background = backgroundTex } }; var buttonBackgroundTex = EditorUtilities.MakeTex(1, 1, new Color(1.0f, 1.0f, 1.0f, 0.05f)); var buttonSelectedTex = EditorUtilities.MakeTex(1, 1, new Color(1.0f, 1.0f, 1.0f, 0.05f)); var buttonNotSelectedText = EditorUtilities.MakeTex(1, 1, new Color(1.0f, 1.0f, 1.0f, 0.2f)); editLayerButton_Background = new GUIStyle { normal = { background = buttonBackgroundTex } }; editLayerButton_NotSelected = new GUIStyle(GUI.skin.label) { normal = { background = buttonNotSelectedText }, alignment = TextAnchor.MiddleCenter }; editLayerButton_Selected = new GUIStyle(GUI.skin.label) { normal = { background = buttonSelectedTex }, alignment = TextAnchor.MiddleCenter }; stylesCreated = true; } if (animationPlayer.layers == null || animationPlayer.layers.Length == 0) { animationPlayer.layers = new AnimationLayer[1]; animationPlayer.layers[0] = AnimationLayer.CreateLayer(); if (animationPlayer.defaultTransition == default(TransitionData)) { animationPlayer.defaultTransition = TransitionData.Linear(.1f); //default shouldn't be snap } return; } if (stateNamesNeedsUpdate) { stateNamesNeedsUpdate = false; allStateNames = new string[animationPlayer.layers.Length][]; for (int i = 0; i < animationPlayer.layers.Length; i++) { var states = animationPlayer.layers[i].states; allStateNames[i] = new string[states.Count]; for (int j = 0; j < states.Count; j++) { allStateNames[i][j] = states[j].Name; } } } if (transitionsNeedsUpdate) { transitionsNeedsUpdate = false; foreach (var layer in animationPlayer.layers) { foreach (var transition in layer.transitions) { transition.FetchStates(layer.states); } } } if (previewer == null) { previewer = new AnimationStatePreviewer(animationPlayer); } }