You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
5.1 KiB
C#
136 lines
5.1 KiB
C#
3 months ago
|
// Animancer // Copyright 2020 Kybernetik //
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Animancer.Editor
|
||
|
{
|
||
|
/// <summary>[Editor-Only] Draws the Inspector GUI for an <see cref="IAnimancerComponent.Playable"/>.</summary>
|
||
|
public sealed class AnimancerPlayableDrawer
|
||
|
{
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
/// <summary>Only get <see cref="AnimancerPlayable.IsGraphPlaying"/> during <see cref="EventType.Layout"/>.</summary>
|
||
|
private bool _IsGraphPlaying;
|
||
|
|
||
|
/// <summary>A lazy list of information about the layers currently being displayed.</summary>
|
||
|
private readonly List<AnimancerLayerDrawer>
|
||
|
LayerInfos = new List<AnimancerLayerDrawer>();
|
||
|
|
||
|
/// <summary>The number of elements in <see cref="LayerInfos"/> that are currently being used.</summary>
|
||
|
private int _LayerCount;
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
/// <summary>Draws the GUI of the <see cref="IAnimancerComponent.Playable"/> if there is only one target.</summary>
|
||
|
public void DoGUI(IAnimancerComponent[] targets)
|
||
|
{
|
||
|
if (targets.Length != 1)
|
||
|
return;
|
||
|
|
||
|
DoGUI(targets[0]);
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
/// <summary>Draws the GUI of the <see cref="IAnimancerComponent.Playable"/>.</summary>
|
||
|
public void DoGUI(IAnimancerComponent target)
|
||
|
{
|
||
|
if (!target.IsPlayableInitialised)
|
||
|
{
|
||
|
DoPlayableNotInitialisedGUI(target);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
|
||
|
// Gather the during the layout event and use the same ones during subsequent events to avoid GUI errors
|
||
|
// in case they change (they shouldn't, but this is also more efficient).
|
||
|
if (Event.current.type == EventType.Layout)
|
||
|
{
|
||
|
AnimancerLayerDrawer.GatherLayerEditors(target.Playable, LayerInfos, out _LayerCount);
|
||
|
_IsGraphPlaying = target.Playable.IsGraphPlaying;
|
||
|
}
|
||
|
|
||
|
if (!_IsGraphPlaying)
|
||
|
{
|
||
|
AnimancerGUI.BeginVerticalBox(GUI.skin.box);
|
||
|
_IsGraphPlaying = EditorGUILayout.Toggle("Is Graph Playing", _IsGraphPlaying);
|
||
|
AnimancerGUI.EndVerticalBox(GUI.skin.box);
|
||
|
|
||
|
if (_IsGraphPlaying)
|
||
|
target.Playable.UnpauseGraph();
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < _LayerCount; i++)
|
||
|
{
|
||
|
LayerInfos[i].DoGUI(target);
|
||
|
}
|
||
|
|
||
|
DoLayerWeightWarningGUI();
|
||
|
|
||
|
if (AnimancerLayerDrawer.ShowUpdatingNodes)
|
||
|
target.Playable.DoUpdateListGUI();
|
||
|
|
||
|
if (EditorGUI.EndChangeCheck() && !_IsGraphPlaying)
|
||
|
target.Playable.Evaluate();
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private void DoPlayableNotInitialisedGUI(IAnimancerComponent target)
|
||
|
{
|
||
|
if (!EditorApplication.isPlaying ||
|
||
|
target.Animator == null ||
|
||
|
EditorUtility.IsPersistent(target.Animator))
|
||
|
return;
|
||
|
|
||
|
EditorGUILayout.HelpBox("Playable is not initialised." +
|
||
|
" It will be initialised automatically when something needs it, such as playing an animation.",
|
||
|
MessageType.Info);
|
||
|
|
||
|
if (AnimancerGUI.TryUseClickEventInLastRect(1))
|
||
|
{
|
||
|
var menu = new GenericMenu();
|
||
|
|
||
|
menu.AddItem(new GUIContent("Initialise"), false, () => target.Playable.Evaluate());
|
||
|
|
||
|
AnimancerEditorUtilities.AddDocumentationLink(menu, "Layer Documentation", "/docs/manual/blending/layers");
|
||
|
|
||
|
menu.ShowAsContext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private void DoLayerWeightWarningGUI()
|
||
|
{
|
||
|
for (int i = 0; i < _LayerCount; i++)
|
||
|
{
|
||
|
var layer = LayerInfos[i].Target;
|
||
|
if (layer.Weight == 1 &&
|
||
|
!layer.IsAdditive &&
|
||
|
layer._Mask == null &&
|
||
|
Mathf.Approximately(layer.GetTotalWeight(), 1))
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
EditorGUILayout.HelpBox(
|
||
|
"There are no Override layers at weight 1, which will likely give undesirable results." +
|
||
|
" Click here for more information.",
|
||
|
MessageType.Warning);
|
||
|
|
||
|
if (AnimancerGUI.TryUseClickEventInLastRect())
|
||
|
EditorUtility.OpenWithDefaultApp(Strings.DocsURLs.Fading);
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|