// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik //
#if UNITY_EDITOR
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
using Animancer.Units;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Animancer.Editor
{
/// [Editor-Only] Persistent settings used by Animancer.
///
/// This asset automatically creates itself when first accessed such as when opening the
/// or viewing an .
///
/// The default location is Assets/Plugins/Animancer/Editor, but you can freely move it (and the whole
/// Animancer folder) anywhere in your project.
///
/// These settings can also be accessed via the Settings in the
/// (Window/Animation/Animancer Tools).
///
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/AnimancerSettings
///
[HelpURL(Strings.DocsURLs.APIDocumentation + "." + nameof(Editor) + "/" + nameof(AnimancerSettings))]
public class AnimancerSettings : ScriptableObject
{
/************************************************************************************************************************/
private static AnimancerSettings _Instance;
///
/// Loads an existing if there is one anywhere in your project, but otherwise
/// creates a new one and saves it in the same folder as this script.
///
public static AnimancerSettings Instance
{
get
{
if (_Instance != null)
return _Instance;
_Instance = AnimancerEditorUtilities.FindAssetOfType();
if (_Instance != null)
return _Instance;
_Instance = CreateInstance();
_Instance.name = "Animancer Settings";
_Instance.hideFlags = HideFlags.DontSaveInBuild;
var script = MonoScript.FromScriptableObject(_Instance);
var path = AssetDatabase.GetAssetPath(script);
path = Path.Combine(Path.GetDirectoryName(path), $"{_Instance.name}.asset");
AssetDatabase.CreateAsset(_Instance, path);
return _Instance;
}
}
/************************************************************************************************************************/
private SerializedObject _SerializedObject;
/// The representing the .
public static SerializedObject SerializedObject
=> Instance._SerializedObject ?? (Instance._SerializedObject = new SerializedObject(Instance));
/************************************************************************************************************************/
private readonly Dictionary
SerializedProperties = new Dictionary();
private static SerializedProperty GetSerializedProperty(string propertyPath)
{
var properties = Instance.SerializedProperties;
if (!properties.TryGetValue(propertyPath, out var property))
{
property = SerializedObject.FindProperty(propertyPath);
properties.Add(propertyPath, property);
}
return property;
}
/************************************************************************************************************************/
/// Base class for groups of fields that can be serialized inside .
public abstract class Group
{
/************************************************************************************************************************/
private string _BasePropertyPath;
/// [Internal] Sets the prefix for .
internal void SetBasePropertyPath(string propertyPath)
{
_BasePropertyPath = propertyPath + ".";
}
/************************************************************************************************************************/
/// Returns a relative to the base of this group.
protected SerializedProperty GetSerializedProperty(string propertyPath)
=> AnimancerSettings.GetSerializedProperty(_BasePropertyPath + propertyPath);
/************************************************************************************************************************/
///
/// Draws a for a
/// property in this group.
///
protected SerializedProperty DoPropertyField(string propertyPath)
{
var property = GetSerializedProperty(propertyPath);
EditorGUILayout.PropertyField(property, true);
return property;
}
/************************************************************************************************************************/
}
/************************************************************************************************************************/
/// Initializes the serialized fields.
protected virtual void OnEnable()
{
if (_TransitionPreviewWindow == null)
_TransitionPreviewWindow = new TransitionPreviewWindow.Settings();
_TransitionPreviewWindow.SetBasePropertyPath(nameof(_TransitionPreviewWindow));
}
/************************************************************************************************************************/
/// Calls on the .
public static new void SetDirty() => EditorUtility.SetDirty(_Instance);
/************************************************************************************************************************/
[SerializeField]
private TransitionPreviewWindow.Settings _TransitionPreviewWindow;
/// Settings for the .
internal static TransitionPreviewWindow.Settings TransitionPreviewWindow => Instance._TransitionPreviewWindow;
/************************************************************************************************************************/
[SerializeField]
private AnimationTimeAttribute.Settings _AnimationTimeFields;
/// Settings for the .
public static AnimationTimeAttribute.Settings AnimationTimeFields => Instance._AnimationTimeFields;
/************************************************************************************************************************/
[SerializeField, Range(0.01f, 1)]
[Tooltip("The amount of time between repaint commands when 'Display Options/Repaint Constantly' is disabled")]
private float _InspectorRepaintInterval = 0.25f;
///
/// The amount of time between repaint commands when
/// is disabled.
///
public static float InspectorRepaintInterval => Instance._InspectorRepaintInterval;
/************************************************************************************************************************/
[SerializeField]
[Seconds(Rule = Validate.Value.IsNotNegative)]
[DefaultValue(0.02f)]
[Tooltip("The amount of time that will be added by a single frame step")]
private float _FrameStep = 0.02f;
/// The amount of time that will be added by a single frame step (in seconds).
public static float FrameStep => Instance._FrameStep;
/************************************************************************************************************************/
[SerializeField]
[Tooltip("The frame rate to use for new animations")]
private float _NewAnimationFrameRate = 12;
/// The frame rate to use for new animations.
public static SerializedProperty NewAnimationFrameRate => GetSerializedProperty(nameof(_NewAnimationFrameRate));
/************************************************************************************************************************/
[SerializeField]
[Tooltip("Should Animancer Event Callbacks be hidden in the Inspector?")]
private bool _HideEventCallbacks;
/// Should Animancer Event Callbacks be hidden in the Inspector?
public static bool HideEventCallbacks => Instance._HideEventCallbacks;
/************************************************************************************************************************/
/// A custom Inspector for .
[CustomEditor(typeof(AnimancerSettings), true), CanEditMultipleObjects]
public class Editor : UnityEditor.Editor
{
/************************************************************************************************************************/
///
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.BeginHorizontal();
using (ObjectPool.Disposable.AcquireContent(out var label, "Disabled Warnings"))
{
EditorGUI.BeginChangeCheck();
var value = EditorGUILayout.EnumFlagsField(label, Validate.PermanentlyDisabledWarnings);
if (EditorGUI.EndChangeCheck())
Validate.PermanentlyDisabledWarnings = (OptionalWarning)value;
}
if (GUILayout.Button("Help", EditorStyles.miniButton, AnimancerGUI.DontExpandWidth))
Application.OpenURL(Strings.DocsURLs.OptionalWarning);
EditorGUILayout.EndHorizontal();
}
/************************************************************************************************************************/
}
/************************************************************************************************************************/
}
}
#endif