123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- #if UNITY_EDITOR
- using Animancer.TransitionLibraries;
- using System;
- using UnityEditor;
- using UnityEngine;
- namespace Animancer.Editor.TransitionLibraries
- {
- /// <summary>[Editor-Only]
- /// A dummy object for tracking the selection within the <see cref="TransitionLibraryWindow"/>
- /// and showing its details in the Inspector.
- /// </summary>
- /// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibrarySelection
- [AnimancerHelpUrl(typeof(TransitionLibrarySelection))]
- public class TransitionLibrarySelection : ScriptableObject
- {
- /************************************************************************************************************************/
- /// <summary>[Editor-Only] Types of objects can be selected.</summary>
- public enum SelectionType
- {
- /// <summary>Nothing selected.</summary>
- None,
- /// <summary>The main library.</summary>
- Library,
- /// <summary>A from-transition.</summary>
- FromTransition,
- /// <summary>A to-transition.</summary>
- ToTransition,
- /// <summary>A fade duration modifier.</summary>
- Modifier,
- }
- /************************************************************************************************************************/
- [SerializeField] private TransitionLibraryWindow _Window;
- [SerializeField] private SelectionType _Type;
- [SerializeField] private int _FromIndex = -1;
- [SerializeField] private int _ToIndex = -1;
- [SerializeField] private int _Version;
- /// <summary>The window this selection is associated with.</summary>
- public TransitionLibraryWindow Window
- => _Window;
- /// <summary>The type of selected object.</summary>
- public SelectionType Type
- => _Type;
- /// <summary>The index of the <see cref="FromTransition"/>.</summary>
- public int FromIndex
- => _FromIndex;
- /// <summary>The index of the <see cref="ToTransition"/>.</summary>
- public int ToIndex
- => _ToIndex;
- /// <summary>The number of times this selection has been changed.</summary>
- public int Version
- => _Version;
- /************************************************************************************************************************/
- /// <summary>The transition the current selection is coming from.</summary>
- public TransitionAssetBase FromTransition { get; private set; }
- /// <summary>The transition the current selection is going to.</summary>
- public TransitionAssetBase ToTransition { get; private set; }
- /// <summary>The <see cref="ITransition.FadeDuration"/> of the current selection.</summary>
- public float FadeDuration { get; private set; }
- /// <summary>Does the current selection have a modified <see cref="FadeDuration"/>?</summary>
- public bool HasModifier { get; private set; }
- /************************************************************************************************************************/
- [NonSerialized] private object _Selected;
- /// <summary>The currently selected object.</summary>
- public object Selected
- {
- get
- {
- Validate();
- return _Selected;
- }
- }
- /************************************************************************************************************************/
- /// <summary>Deselects the current object if it isn't valid.</summary>
- public bool Validate()
- {
- if (IsValid())
- return true;
- Deselect();
- return false;
- }
- /// <summary>Is the current selection valid?</summary>
- public bool IsValid()
- {
- if (this == null ||
- _Window == null ||
- Selection.activeObject != this)
- return false;
- var library = _Window.SourceObject;
- if (library == null)
- return false;
- FromTransition = null;
- ToTransition = null;
- FadeDuration = float.NaN;
- HasModifier = false;
- switch (_Type)
- {
- case SelectionType.Library:
- name = "Transition Library";
- _Selected = library;
- return library != null;
- case SelectionType.FromTransition:
- name = "From Transition";
- if (!_Window.Data.Transitions.TryGet(_FromIndex, out var transition))
- return false;
- FromTransition = transition;
- FadeDuration = transition.TryGetFadeDuration();
- _Selected = transition;
- return true;
- case SelectionType.ToTransition:
- name = "To Transition";
- if (!_Window.Data.Transitions.TryGet(_ToIndex, out transition))
- return false;
- ToTransition = transition;
- FadeDuration = transition.TryGetFadeDuration();
- _Selected = transition;
- return true;
- case SelectionType.Modifier:
- name = "Transition Modifier";
- var hasTransitions = _Window.Data.TryGetTransition(_FromIndex, out transition);
- FromTransition = transition;
- hasTransitions |= _Window.Data.TryGetTransition(_ToIndex, out transition);
- ToTransition = transition;
- if (_Window.Data.TryGetModifier(_FromIndex, _ToIndex, out var modifier))
- {
- HasModifier = true;
- }
- else if (hasTransitions)
- {
- modifier = modifier.WithFadeDuration(transition.TryGetFadeDuration());
- }
- else
- {
- return false;
- }
- FadeDuration = modifier.FadeDuration;
- _Selected = modifier;
- return true;
- default:
- return false;
- };
- }
- /************************************************************************************************************************/
- /// <summary>Sets the <see cref="Selected"/> object.</summary>
- /// <remarks>
- /// We can't simply set the <see cref="Selection.activeObject"/>
- /// because it might not be a <see cref="UnityEngine.Object"/>
- /// and if it is then we don't want the Project window to move to it.
- /// <para></para>
- /// So instead, we select this dummy object and <see cref="TransitionLibrarySelectionEditor"/>
- /// draws a custom Inspector for the target object.
- /// </remarks>
- public void Select(
- TransitionLibraryWindow window,
- object select,
- int index,
- SelectionType type)
- {
- switch (type)
- {
- case SelectionType.Library:
- _FromIndex = -1;
- _ToIndex = -1;
- break;
- case SelectionType.FromTransition:
- _FromIndex = index;
- _ToIndex = -1;
- break;
- case SelectionType.ToTransition:
- _FromIndex = -1;
- _ToIndex = index;
- break;
- case SelectionType.Modifier:
- if (select is TransitionModifierDefinition modifier)
- {
- _FromIndex = modifier.FromIndex;
- _ToIndex = modifier.ToIndex;
- break;
- }
- else
- {
- Deselect();
- return;
- }
- default:
- Deselect();
- throw new ArgumentException($"Unhandled {nameof(SelectionType)}", nameof(type));
- }
- _Window = window;
- _Type = type;
- _Selected = select;
- _Version++;
- Selection.activeObject = this;
- Validate();
- }
- /************************************************************************************************************************/
- /// <summary>Clears the <see cref="Selected"/> object.</summary>
- public void Deselect()
- {
- _Window = null;
- _Type = default;
- _FromIndex = -1;
- _ToIndex = -1;
- _Selected = null;
- _Version++;
- if (Selection.activeObject == this)
- Selection.activeObject = null;
- }
- /************************************************************************************************************************/
- /// <summary>Handles selection changes.</summary>
- public void OnSelectionChange()
- {
- if (Selection.activeObject == this)
- return;
- Deselect();
- if (_Window != null)
- _Window.Repaint();
- }
- /************************************************************************************************************************/
- /// <summary>Selects this object if it contains a valid selection.</summary>
- protected virtual void OnEnable()
- {
- if (Selected != null)
- Selection.activeObject = this;
- }
- /************************************************************************************************************************/
- }
- }
- #endif
|