// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
#if UNITY_EDITOR
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Animancer.Editor
{
/// [Editor-Only]
/// Allows any object to be highlighted in the GUI like with
/// .
///
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/ObjectHighlightGUI
///
public static class ObjectHighlightGUI
{
/************************************************************************************************************************/
/// The highlight will start by expanding then contracting over this duration.
public const double ExpandDuration = 0.5f;
/// After the the highlight will fade out over this duration.
public const double LingerDuration = 2;
/// The size that the highlight expands to.
public const float HighlightSize = 5;
/// The colour used to highlight the pinged object.
public static readonly Color HighlightColor = EditorGUIUtility.isProSkin
? new(0.8f, 0.6f, 0.2f, 0.4f)
: new(1, 0.75f, 0.25f, 0.4f);
///
public static double CurrentTime => EditorApplication.timeSinceStartup;
/************************************************************************************************************************/
/// The object currently being highlighted.
public static object Target { get; private set; }
/// The time when the highlight was started.
public static double StartTime { get; private set; }
/************************************************************************************************************************/
/// Sets the target object to start highlighting it.
public static void Highlight(object target)
{
if (target is Object unityObject)
{
EditorGUIUtility.PingObject(unityObject);
return;
}
Target = target;
StartTime = CurrentTime;
}
/************************************************************************************************************************/
/// Draws the highlight if the given `target` is the current .
public static void Draw(Rect area, object target)
{
if (Target != target ||
Event.current.type != EventType.Repaint)
return;
var elapsedTime = CurrentTime - StartTime;
if (elapsedTime < ExpandDuration + LingerDuration)
{
if (elapsedTime < ExpandDuration)
{
var size = HighlightSize * Mathf.Sin((float)(elapsedTime / ExpandDuration * Mathf.PI));
area.x -= size;
area.y -= size;
area.width += size * 2;
area.height += size * 2;
}
elapsedTime /= ExpandDuration + LingerDuration;
var color = HighlightColor;
color.a *= (float)(1 - elapsedTime);
EditorGUI.DrawRect(area, color);
InternalEditorUtility.RepaintAllViews();
}
else
{
Target = null;
}
}
/************************************************************************************************************************/
}
}
#endif