/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { var sprites = Sprites; if (_NamesAreDirty) { _NamesAreDirty = false; GatherNameToSprites(sprites, NameToSprites); Names.AddRange(NameToSprites.Keys); } GUI.enabled = false; _Display.DoLayoutList(); GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); GUI.enabled = sprites.Count > 0; if (GUILayout.Button("Generate")) { AnimancerGUI.Deselect(); GenerateAnimationsBySpriteName(sprites); } } GUILayout.EndHorizontal(); GUI.enabled = true; EditorGUILayout.HelpBox("This function is also available via:" + "\n - The 'Assets/Create/Animancer' menu." + "\n - The Cog icon in the top right of the Inspector for Sprite and Texture assets", MessageType.Info); }
/************************************************************************************************************************/ private void Apply() { AnimancerGUI.Deselect(); _HasBeenModified = false; var targets = this.targets; var path = AssetDatabase.GetAssetPath(targets[0]); var importer = (TextureImporter)AssetImporter.GetAtPath(path); var spriteSheet = importer.spritesheet; var hasError = false; for (int i = 0; i < targets.Length; i++) { Apply((Sprite)targets[i], spriteSheet, ref hasError); } if (!hasError) { importer.spritesheet = spriteSheet; EditorUtility.SetDirty(importer); importer.SaveAndReimport(); } for (int i = 0; i < targets.Length; i++) { if (targets[i] == null) { return; } } serializedObject.Update(); }
/************************************************************************************************************************/ private void Apply() { AnimancerGUI.Deselect(); _HasBeenModified = false; var targets = this.targets; var hasError = false; for (int i = 0; i < _Targets.Length; i++) { var target = _Targets[i]; var spriteSheet = target.Importer.spritesheet; Apply(target.Sprite, spriteSheet, ref hasError); if (!hasError) { target.Importer.spritesheet = spriteSheet; EditorUtility.SetDirty(target.Importer); target.Importer.SaveAndReimport(); } } for (int i = 0; i < targets.Length; i++) { if (targets[i] == null) { return; } } serializedObject.Update(); }
/************************************************************************************************************************/ #endregion /************************************************************************************************************************/ #region Models /************************************************************************************************************************/ private static void DoModelsGUI() { var property = ModelsProperty; var count = property.arraySize = EditorGUILayout.DelayedIntField(nameof(Models), property.arraySize); // Drag and Drop to add model. var area = GUILayoutUtility.GetLastRect(); AnimancerGUI.HandleDragAndDrop<GameObject>(area, (gameObject) => { return EditorUtility.IsPersistent(gameObject) && !Models.Contains(gameObject) && gameObject.GetComponentInChildren<Animator>() != null; }, (gameObject) => { var modelsProperty = ModelsProperty;// Avoid Closure. modelsProperty.serializedObject.Update(); var i = modelsProperty.arraySize; modelsProperty.arraySize = i + 1; modelsProperty.GetArrayElementAtIndex(i).objectReferenceValue = gameObject; modelsProperty.serializedObject.ApplyModifiedProperties(); }); if (count == 0) return; property.isExpanded = EditorGUI.Foldout(area, property.isExpanded, GUIContent.none, true); if (!property.isExpanded) return; EditorGUI.indentLevel++; var model = property.GetArrayElementAtIndex(0); for (int i = 0; i < count; i++) { GUILayout.BeginHorizontal(); EditorGUILayout.ObjectField(model); if (GUILayout.Button("x", AnimancerGUI.MiniButton)) { Serialization.RemoveArrayElement(property, i); property.serializedObject.ApplyModifiedProperties(); AnimancerGUI.Deselect(); GUIUtility.ExitGUI(); return; } GUILayout.Space(EditorStyles.objectField.margin.right); GUILayout.EndHorizontal(); model.Next(false); } EditorGUI.indentLevel--; }
/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { EditorGUILayout.HelpBox(ReferencesLostMessage, MessageType.Warning); BeginChangeCheck(); var newName = EditorGUILayout.TextField("New Name", _NewName); if (EndChangeCheck(ref _NewName, newName)) { _NamesAreDirty = true; } BeginChangeCheck(); var digits = EditorGUILayout.IntField("Minimum Digits", _MinimumDigits); if (EndChangeCheck(ref _MinimumDigits, Mathf.Max(digits, 1))) { _NamesAreDirty = true; } UpdateNames(); GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); _SpritesDisplay.DoLayoutList(); GUILayout.EndVertical(); GUILayout.BeginVertical(); _NamesDisplay.DoLayoutList(); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); GUI.enabled = _NewName.Length > 0; if (GUILayout.Button("Clear")) { AnimancerGUI.Deselect(); RecordUndo(); _NewName = ""; _NamesAreDirty = true; } GUI.enabled = _SpritesDisplay.list.Count > 0; if (GUILayout.Button("Apply")) { AnimancerGUI.Deselect(); AskAndApply(); } } GUILayout.EndHorizontal(); }
/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { base.DoBodyGUI(); GatherBindings(); GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); GUI.enabled = false; _OldBindingPathsDisplay.DoLayoutList(); GUI.enabled = true; GUILayout.EndVertical(); GUILayout.BeginVertical(); _NewBindingPathsDisplay.DoLayoutList(); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUI.enabled = Animation != null; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); if (GUILayout.Button("Reset")) { AnimancerGUI.Deselect(); RecordUndo(); _NewBindingPaths.Clear(); _OldBindingPathsAreDirty = true; } if (GUILayout.Button("Copy All")) { AnimancerGUI.Deselect(); CopyAll(); } if (GUILayout.Button("Paste All")) { AnimancerGUI.Deselect(); PasteAll(); } if (GUILayout.Button("Save As")) { if (SaveAs()) { _OldBindingPathsAreDirty = true; } } } GUILayout.EndHorizontal(); }
/************************************************************************************************************************/ /// <summary>Removes the event at the specified `index`.</summary> public static void RemoveEvent(Context context, int index) { // If it's an End Event, set it to NaN. if (index >= context.Times.Count - 1) { context.Times.GetElement(index).floatValue = float.NaN; if (context.Callbacks.Count > index) { context.Callbacks.Count--; } AnimancerGUI.Deselect(); // Update the runtime sequence accordingly. var events = context.Sequence?.InitializedEvents; if (events != null) { events.endEvent = new AnimancerEvent(float.NaN, null); } } else// Otherwise remove it. { context.Times.Property.DeleteArrayElementAtIndex(index); context.Times.Count--; // Update the runtime sequence accordingly. var events = context.Sequence?.InitializedEvents; if (events != null) { events.Remove(index); } if (index < context.Names.Count) { context.Names.Property.DeleteArrayElementAtIndex(index); context.Names.Count--; } if (index < context.Callbacks.Count) { context.Callbacks.Property.DeleteArrayElementAtIndex(index); context.Callbacks.Count--; } } }
/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { base.DoBodyGUI(); GatherOldSprites(); GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); GUI.enabled = false; _OldSpriteDisplay.DoLayoutList(); GUI.enabled = true; GUILayout.EndVertical(); GUILayout.BeginVertical(); _NewSpriteDisplay.DoLayoutList(); GUILayout.EndVertical(); HandleDragAndDropIntoList(GUILayoutUtility.GetLastRect(), _NewSprites, overwrite: true); } GUILayout.EndHorizontal(); GUI.enabled = Animation != null; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); if (GUILayout.Button("Reset")) { AnimancerGUI.Deselect(); RecordUndo(); _NewSprites.Clear(); _OldSpritesAreDirty = true; } if (GUILayout.Button("Save As")) { if (SaveAs()) { _OldSpritesAreDirty = true; } } } GUILayout.EndHorizontal(); }
private void DoAllEventsGUI(ref Rect area, Context context) { var currentEvent = Event.current; var originalEventType = currentEvent.type; if (originalEventType == EventType.Used) { return; } var rootControlID = GUIUtility.GetControlID(EventTimeHash - 1, FocusType.Passive); var eventCount = Mathf.Max(1, context.Times.Count); for (int i = 0; i < eventCount; i++) { var controlID = GUIUtility.GetControlID(EventTimeHash + i, FocusType.Passive); if (rootControlID == _HotControlAdjustRoot && _SelectedEventToHotControl > 0 && i == context.SelectedEvent) { GUIUtility.hotControl = GUIUtility.keyboardControl = controlID + _SelectedEventToHotControl; _SelectedEventToHotControl = 0; _HotControlAdjustRoot = -1; } DoEventGUI(ref area, context, i, false); if (currentEvent.type == EventType.Used && originalEventType == EventType.MouseUp) { context.SelectedEvent = i; if (SortEvents(context)) { _SelectedEventToHotControl = GUIUtility.keyboardControl - controlID; _HotControlAdjustRoot = rootControlID; AnimancerGUI.Deselect(); } GUIUtility.ExitGUI(); } } }
/************************************************************************************************************************/ /// <summary>Calls <see cref="Panel.SaveModifiedAsset"/> on the animation.</summary> protected bool SaveAs() { AnimancerGUI.Deselect(); if (SaveModifiedAsset( "Save Modified Animation", "Where would you like to save the new animation?", _Animation, Modify)) { _Animation = null; OnAnimationChanged(); return(true); } else { return(false); } }
/************************************************************************************************************************/ /// <summary>Removes the event at the specified `index`.</summary> public static void RemoveEvent(Context context, int index) { // Only remove the time if it is not an End Event. if (index < context.TimeCount - 1) { context.Times.DeleteArrayElementAtIndex(index); context.TimeCount--; } else// If it was an End Event, prevent the selection from moving on to later GUI elements. { AnimancerGUI.Deselect(); } if (index < context.CallbackCount) { context.Callbacks.DeleteArrayElementAtIndex(index); context.CallbackCount--; } }
/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { GUILayout.BeginVertical(); _TexturesDisplay.DoLayoutList(); GUILayout.EndVertical(); HandleDragAndDropIntoList(GUILayoutUtility.GetLastRect(), _Textures, overwrite: false); RemoveDuplicates(_Textures); BeginChangeCheck(); var padding = EditorGUILayout.IntField("Padding", _Padding); EndChangeCheck(ref _Padding, padding); BeginChangeCheck(); var maximumSize = EditorGUILayout.IntField("Maximum Size", _MaximumSize); maximumSize = Math.Max(maximumSize, 16); EndChangeCheck(ref _MaximumSize, maximumSize); GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); GUI.enabled = _Textures.Count > 0; if (GUILayout.Button("Clear")) { AnimancerGUI.Deselect(); RecordUndo(); _Textures.Clear(); } GUI.enabled = _Textures.Count > 0; if (GUILayout.Button("Pack")) { AnimancerGUI.Deselect(); Pack(); } } GUILayout.EndHorizontal(); }
/************************************************************************************************************************/ private void Revert() { AnimancerGUI.Deselect(); _HasBeenModified = false; serializedObject.Update(); }
/************************************************************************************************************************/ /// <inheritdoc/> public override void DoBodyGUI() { var area = AnimancerGUI.LayoutSingleLineRect(); area.xMin += 4; using (ObjectPool.Disposable.AcquireContent(out var label, "Offset Rects", null, false)) area = EditorGUI.PrefixLabel(area, label); BeginChangeCheck(); var selected = (OffsetRectMode)GUI.Toolbar(area, (int)_RectMode, OffsetRectModes); EndChangeCheck(ref _RectMode, selected); using (var property = _SerializedProperty.Copy()) { property.serializedObject.Update(); var depth = property.depth; while (property.Next(false) && property.depth >= depth) { EditorGUILayout.PropertyField(property, true); } property.serializedObject.ApplyModifiedProperties(); } GUI.enabled = false; for (int i = 0; i < Sprites.Count; i++) { if (_ShowDetails) { GUILayout.BeginVertical(GUI.skin.box); } var sprite = Sprites[i] = (Sprite)EditorGUILayout.ObjectField(Sprites[i], typeof(Sprite), false); if (_ShowDetails) { if (_RectMode != OffsetRectMode.None) { EditorGUILayout.RectField("Rect", sprite.rect); } if (_SetPivot) { EditorGUILayout.Vector2Field("Pivot", sprite.pivot); } if (_SetBorder) { EditorGUILayout.Vector4Field("Border", sprite.border); } GUILayout.EndVertical(); } } GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); GUI.enabled = Sprites.Count > 0 && IsValidModification(); if (GUILayout.Button("Apply")) { AnimancerGUI.Deselect(); AskAndApply(); } } GUILayout.EndHorizontal(); }
/// <summary>Draws the time field for the event at the specified `index`.</summary> public static void DoEventTimeGUI(ref Rect area, Context context, int index, bool autoSort, out string callbackLabel) { EditorGUI.BeginChangeCheck(); area.height = AnimancerGUI.LineHeight; var timeArea = area; AnimancerGUI.NextVerticalArea(ref area); GUIContent timeLabel; float defaultTime; bool isEndEvent; GetEventLabels(index, context, out timeLabel, out callbackLabel, out defaultTime, out isEndEvent); var length = context.TransitionContext.MaximumDuration; float normalizedTime; if (index < context.TimeCount) { var timeProperty = context.GetTime(index); var wasEditingTextField = EditorGUIUtility.editingTextField; if (!wasEditingTextField) { _PreviousTime = float.NaN; } EditorGUI.BeginChangeCheck(); timeLabel = EditorGUI.BeginProperty(area, timeLabel, timeProperty); normalizedTime = AnimancerGUI.DoOptionalTimeField( ref timeArea, timeLabel, timeProperty.floatValue, true, length, defaultTime); EditorGUI.EndProperty(); var isEditingTextField = EditorGUIUtility.editingTextField; if (EditorGUI.EndChangeCheck() || (wasEditingTextField && !isEditingTextField)) { if (isEndEvent) { timeProperty.floatValue = normalizedTime; } else if (float.IsNaN(normalizedTime)) { RemoveEvent(context, index); AnimancerGUI.Deselect(); } else if (!autoSort && isEditingTextField) { _PreviousTime = normalizedTime; } else { if (!float.IsNaN(_PreviousTime)) { if (Event.current.keyCode != KeyCode.Escape) { normalizedTime = _PreviousTime; AnimancerGUI.Deselect(); } _PreviousTime = float.NaN; } WrapEventTime(context, ref normalizedTime); timeProperty.floatValue = normalizedTime; if (autoSort) { SortEvents(context); } } GUI.changed = true; } } else// Dummy End Event. { Debug.Assert(index == 0, "This is assumed to be a dummy end event, which should only be at index 0"); EditorGUI.BeginChangeCheck(); EditorGUI.BeginProperty(timeArea, GUIContent.none, context.Times); normalizedTime = AnimancerGUI.DoOptionalTimeField( ref timeArea, timeLabel, float.NaN, true, length, defaultTime, true); EditorGUI.EndProperty(); if (EditorGUI.EndChangeCheck() && !float.IsNaN(normalizedTime)) { context.TimeCount = 1; var timeProperty = context.GetTime(0); timeProperty.floatValue = normalizedTime; } } if (EditorGUI.EndChangeCheck()) { TransitionPreviewWindow.SetPreviewNormalizedTime(normalizedTime); if (Event.current.type != EventType.Layout) { GUIUtility.ExitGUI(); } } }
/// <summary>Draws the time field for the event at the specified `index`.</summary> public static void DoTimeGUI(ref Rect area, Context context, int index, bool autoSort, string timeLabel, float defaultTime, bool isEndEvent) { EditorGUI.BeginChangeCheck(); area.height = EventTimeAttribute.GetPropertyHeight(null, null); var timeArea = area; AnimancerGUI.NextVerticalArea(ref area); float normalizedTime; using (ObjectPool.Disposable.AcquireContent(out var label, timeLabel, isEndEvent ? Strings.Tooltips.EndTime : Strings.Tooltips.CallbackTime)) { var length = context.TransitionContext?.MaximumDuration ?? float.NaN; if (index < context.Times.Count) { var timeProperty = context.Times.GetElement(index); if (timeProperty == null)// Multi-selection screwed up the property retrieval. { EditorGUI.BeginChangeCheck(); label = EditorGUI.BeginProperty(timeArea, label, context.Times.Property); if (isEndEvent) { AnimationTimeAttribute.nextDefaultValue = defaultTime; } normalizedTime = float.NaN; EventTimeAttribute.OnGUI(timeArea, label, ref normalizedTime); EditorGUI.EndProperty(); if (EditorGUI.EndChangeCheck()) { context.Times.Count = context.Times.Count; timeProperty = context.Times.GetElement(index); timeProperty.floatValue = normalizedTime; SyncEventTimeChange(context, index, normalizedTime); } } else// Event time property was correctly retrieved. { var wasEditingTextField = EditorGUIUtility.editingTextField; if (!wasEditingTextField) { _PreviousTime = float.NaN; } EditorGUI.BeginChangeCheck(); label = EditorGUI.BeginProperty(timeArea, label, timeProperty); if (isEndEvent) { AnimationTimeAttribute.nextDefaultValue = defaultTime; } normalizedTime = timeProperty.floatValue; EventTimeAttribute.OnGUI(timeArea, label, ref normalizedTime); EditorGUI.EndProperty(); if (AnimancerGUI.TryUseClickEvent(timeArea, 2)) { normalizedTime = float.NaN; } var isEditingTextField = EditorGUIUtility.editingTextField; if (EditorGUI.EndChangeCheck() || (wasEditingTextField && !isEditingTextField)) { if (float.IsNaN(normalizedTime)) { RemoveEvent(context, index); AnimancerGUI.Deselect(); } else if (isEndEvent) { timeProperty.floatValue = normalizedTime; SyncEventTimeChange(context, index, normalizedTime); } else if (!autoSort && isEditingTextField) { _PreviousTime = normalizedTime; } else { if (!float.IsNaN(_PreviousTime)) { if (Event.current.keyCode != KeyCode.Escape) { normalizedTime = _PreviousTime; AnimancerGUI.Deselect(); } _PreviousTime = float.NaN; } WrapEventTime(context, ref normalizedTime); timeProperty.floatValue = normalizedTime; SyncEventTimeChange(context, index, normalizedTime); if (autoSort) { SortEvents(context); } } GUI.changed = true; } } } else// Dummy End Event (when there are no event times). { AnimancerUtilities.Assert(index == 0, "Dummy end event index != 0"); EditorGUI.BeginChangeCheck(); EditorGUI.BeginProperty(timeArea, GUIContent.none, context.Times.Property); AnimationTimeAttribute.nextDefaultValue = defaultTime; normalizedTime = float.NaN; EventTimeAttribute.OnGUI(timeArea, label, ref normalizedTime); EditorGUI.EndProperty(); if (EditorGUI.EndChangeCheck() && !float.IsNaN(normalizedTime)) { context.Times.Count = 1; var timeProperty = context.Times.GetElement(0); timeProperty.floatValue = normalizedTime; SyncEventTimeChange(context, 0, normalizedTime); } } } if (EditorGUI.EndChangeCheck()) { var eventType = Event.current.type; if (eventType == EventType.Layout) { return; } if (eventType == EventType.Used) { normalizedTime = UnitsAttribute.GetDisplayValue(normalizedTime, defaultTime); TransitionPreviewWindow.PreviewNormalizedTime = normalizedTime; } GUIUtility.ExitGUI(); } }