ObjectHighlightGUI.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. using UnityEditorInternal;
  5. using UnityEngine;
  6. using Object = UnityEngine.Object;
  7. namespace Animancer.Editor
  8. {
  9. /// <summary>[Editor-Only]
  10. /// Allows any object to be highlighted in the GUI like with
  11. /// <see cref="EditorGUIUtility.PingObject(Object)"/>.
  12. /// </summary>
  13. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/ObjectHighlightGUI
  14. ///
  15. public static class ObjectHighlightGUI
  16. {
  17. /************************************************************************************************************************/
  18. /// <summary>The highlight will start by expanding then contracting over this duration.</summary>
  19. public const double ExpandDuration = 0.5f;
  20. /// <summary>After the <see cref="ExpandDuration"/> the highlight will fade out over this duration.</summary>
  21. public const double LingerDuration = 2;
  22. /// <summary>The size that the highlight expands to.</summary>
  23. public const float HighlightSize = 5;
  24. /// <summary>The colour used to highlight the pinged object.</summary>
  25. public static readonly Color HighlightColor = EditorGUIUtility.isProSkin
  26. ? new(0.8f, 0.6f, 0.2f, 0.4f)
  27. : new(1, 0.75f, 0.25f, 0.4f);
  28. /// <summary><see cref="EditorApplication.timeSinceStartup"/></summary>
  29. public static double CurrentTime => EditorApplication.timeSinceStartup;
  30. /************************************************************************************************************************/
  31. /// <summary>The object currently being highlighted.</summary>
  32. public static object Target { get; private set; }
  33. /// <summary>The time when the highlight was started.</summary>
  34. public static double StartTime { get; private set; }
  35. /************************************************************************************************************************/
  36. /// <summary>Sets the target object to start highlighting it.</summary>
  37. public static void Highlight(object target)
  38. {
  39. if (target is Object unityObject)
  40. {
  41. EditorGUIUtility.PingObject(unityObject);
  42. return;
  43. }
  44. Target = target;
  45. StartTime = CurrentTime;
  46. }
  47. /************************************************************************************************************************/
  48. /// <summary>Draws the highlight if the given `target` is the current <see cref="Target"/>.</summary>
  49. public static void Draw(Rect area, object target)
  50. {
  51. if (Target != target ||
  52. Event.current.type != EventType.Repaint)
  53. return;
  54. var elapsedTime = CurrentTime - StartTime;
  55. if (elapsedTime < ExpandDuration + LingerDuration)
  56. {
  57. if (elapsedTime < ExpandDuration)
  58. {
  59. var size = HighlightSize * Mathf.Sin((float)(elapsedTime / ExpandDuration * Mathf.PI));
  60. area.x -= size;
  61. area.y -= size;
  62. area.width += size * 2;
  63. area.height += size * 2;
  64. }
  65. elapsedTime /= ExpandDuration + LingerDuration;
  66. var color = HighlightColor;
  67. color.a *= (float)(1 - elapsedTime);
  68. EditorGUI.DrawRect(area, color);
  69. InternalEditorUtility.RepaintAllViews();
  70. }
  71. else
  72. {
  73. Target = null;
  74. }
  75. }
  76. /************************************************************************************************************************/
  77. }
  78. }
  79. #endif