123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- #if UNITY_EDITOR && UNITY_IMGUI
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- using static Animancer.Editor.AnimancerGUI;
- namespace Animancer.Editor.Previews
- {
- /// <summary>[Editor-Only] GUI utilities for <see cref="AnimancerPreviewObject"/>.</summary>
- /// https://kybernetik.com.au/animancer/api/Animancer.Editor.Previews/AnimancerPreviewObjectGUI
- public static class AnimancerPreviewObjectGUI
- {
- /************************************************************************************************************************/
- /// <summary>Calculates the pixel height required to draw the `preview`.</summary>
- public static float CalculateHeight(AnimancerPreviewObject preview)
- {
- var lines = 1;
- var instanceAnimators = preview.InstanceAnimators;
- if (instanceAnimators != null &&
- instanceAnimators.Length > 1)
- lines++;
- return AnimancerGUI.CalculateHeight(lines);
- }
- /************************************************************************************************************************/
- /// <summary>Draws the model selection GUI.</summary>
- public static void DoModelGUI(AnimancerPreviewObject preview)
- {
- var area = LayoutRect(CalculateHeight(preview));
- DoModelGUI(area, preview);
- }
- /************************************************************************************************************************/
- /// <summary>Draws the model selection GUI.</summary>
- public static void DoModelGUI(Rect area, AnimancerPreviewObject preview)
- {
- var root = preview.OriginalObject;
- var model = root != null ? root.gameObject : null;
- EditorGUI.BeginChangeCheck();
- var warning = GetModelWarning(model, preview);
- var color = GUI.color;
- if (warning != null)
- GUI.color = WarningFieldColor;
- using (var label = PooledGUIContent.Acquire("Model"))
- {
- var objectFieldArea = StealLineFromTop(ref area);
- if (DoDropdownObjectFieldGUI(objectFieldArea, label, true, ref model))
- {
- var menu = new GenericMenu();
- menu.AddItem(
- new("Default Humanoid"),
- model != null && model == TransitionPreviewSettings.GetOrCreateDefaultHumanoid(null),
- () => preview.OriginalObject
- = TransitionPreviewSettings.GetOrCreateDefaultHumanoid(preview.InstanceRoot).transform);
- menu.AddItem(
- new("Default Sprite"),
- model != null && model == TransitionPreviewSettings.GetDefaultSpriteIfAlreadyCreated(),
- () => preview.OriginalObject
- = TransitionPreviewSettings.GetOrCreateDefaultSprite(preview.InstanceRoot).transform);
- var persistentModels = TransitionPreviewSettings.Models;
- var temporaryModels = TemporarySettings.PreviewModels;
- if (persistentModels.Count == 0 && temporaryModels.Count == 0)
- {
- menu.AddDisabledItem(new("No model prefabs have been used yet"));
- }
- else
- {
- AddModelSelectionFunctions(menu, preview, persistentModels, model);
- AddModelSelectionFunctions(menu, preview, temporaryModels, model);
- }
- menu.ShowAsContext();
- }
- }
- GUI.color = color;
- if (EditorGUI.EndChangeCheck())
- preview.OriginalObject = model != null ? model.transform : null;
- if (warning != null)
- EditorGUILayout.HelpBox(warning, MessageType.Warning, true);
- DoAnimatorSelectorGUI(preview);
- }
- /************************************************************************************************************************/
- /// <summary>Adds menu functions for selecting each of the `models`.</summary>
- private static void AddModelSelectionFunctions(
- GenericMenu menu,
- AnimancerPreviewObject preview,
- List<GameObject> models,
- GameObject selected)
- {
- for (int i = models.Count - 1; i >= 0; i--)
- {
- var model = models[i];
- var path = AssetDatabase.GetAssetPath(model);
- if (!string.IsNullOrEmpty(path))
- path = path.Replace('/', '\\');
- else
- path = model.name;
- menu.AddItem(new(path), model == selected,
- () => preview.OriginalObject = model.transform);
- }
- }
- /************************************************************************************************************************/
- /// <summary>Returns a warning about the selected model or <c>null</c>.</summary>
- private static string GetModelWarning(
- GameObject model,
- AnimancerPreviewObject preview)
- {
- if (model == null)
- return "No Model is selected so nothing can be previewed.";
- if (preview.SelectedInstanceAnimator == null)
- return "The selected Model has no Animator component.";
- return null;
- }
- /************************************************************************************************************************/
- /// <summary>
- /// Draws a button for selecting which <see cref="Animator"/> to control if there's more than one.
- /// </summary>
- private static void DoAnimatorSelectorGUI(AnimancerPreviewObject preview)
- {
- var instanceAnimators = preview.InstanceAnimators;
- if (instanceAnimators == null ||
- instanceAnimators.Length <= 1)
- return;
- var area = LayoutSingleLineRect(SpacingMode.After);
- var labelArea = StealFromLeft(ref area, EditorGUIUtility.labelWidth, StandardSpacing);
- GUI.Label(labelArea, nameof(Animator));
- var selectedAnimator = preview.SelectedInstanceAnimator;
- using (var label = PooledGUIContent.Acquire(
- selectedAnimator != null ? selectedAnimator.name : "None"))
- {
- var clicked = EditorGUI.DropdownButton(area, label, FocusType.Passive);
- if (!clicked)
- return;
- var menu = new GenericMenu();
- for (int i = 0; i < instanceAnimators.Length; i++)
- {
- var animator = instanceAnimators[i];
- var index = i;
- menu.AddItem(new(animator.name), animator == selectedAnimator, () =>
- {
- preview.SetSelectedAnimator(index);
- });
- }
- menu.ShowAsContext();
- }
- }
- /************************************************************************************************************************/
- private static DragAndDropHandler<GameObject> _ModelDropHandler;
- private static AnimancerPreviewObject _ModelDropPreview;
- /// <summary>Handles drag and drop events for preview models.</summary>
- public static void HandleDragAndDrop(Rect area, AnimancerPreviewObject preview)
- {
- _ModelDropPreview = preview;
- _ModelDropHandler ??= (gameObject, isDrop) =>
- {
- if (!gameObject.TryGetComponent<Animator>(out _))
- return false;
- if (isDrop)
- _ModelDropPreview.OriginalObject = gameObject.transform;
- return true;
- };
- _ModelDropPreview = null;
- }
- /************************************************************************************************************************/
- }
- }
- #endif
|