December 12, 2014  by  
Tags: , ,

At first glance, flashing text in a custom Unity editor window may sound like an annoyance, and it certainly can be if used inappropriately. But it can be a useful tool for catching a user’s attention if used responsibly. I use it in a few of my custom editors to alert the user to various situations:

  • Missing components. For example, my vertex painters won’t work if the selected game object does not contain a mesh component.
  • When you’re locking standard scene selection. For example, when my vertex painters are in “Paint Mode”, you cannot select scene objects when clicking in the scene. This can be confusing if you forget you are in “Paint Mode”, or you are using the tool for the first time.
  • Warning messages. “Changes cannot be undone” might be a good candidate.

How I use it

 
'Component missing' error message

‘Component missing’ error message

'Scene selection locked' info message

‘Scene selection locked’ info message

How it works

Really the only thing you need to understand is that you cannot use Time.DeltaTime in edit mode, because the game is not running. This means you can’t use tools like iTween to change the color of your text, because it rely’s on Time.DeltaTime to perform all of it’s calculations (yes, even FloatUpdate). So, in order to make the animation happen, you’ll have to write a little extra code yourself. EditorApplication.update is called approximately 100 times per second, even in edit mode, so you can perform your animation logic in there.

Feel free to use or modify the code below for any purpose. I only use it to animate text color, but you could easily adapt it to perform animations of any kind. Maybe you’d like to have a small, animated company logo at the top of editors you release to the asset store for example. The sky’s the limit. Hopefully this code will be of use to someone.

  1. namespace Assets.Editor
  2. {
  3. using UnityEditor;
  4. using UnityEngine;
  5. /// <summary>
  6. /// Class definition for FlashingTextInEditorWindow.cs.
  7. /// </summary>
  8. public class FlashingTextInEditorWindow : EditorWindow
  9. {
  10. private const float FlashingTextCycleDuration = 2.0f;
  11. private Color _flashingTextColor = Color.red;
  12. private float _realTimeLastFrame;
  13. private bool _fadingColorIn;
  14. /// <summary>
  15. /// Register our editor window.
  16. /// </summary>
  17. [MenuItem("Sector12/Flashing Text")]
  18. protected static void Init()
  19. {
  20. GetWindow(typeof(FlashingTextInEditorWindow), false, "Flashing Text");
  21. }
  22. /// <summary>
  23. /// Setup a hook into an update method so that we can display flashing text
  24. /// over time in the editor window.
  25. /// </summary>
  26. private void OnEnable()
  27. {
  28. // Make sure we're never registered twice
  29. EditorApplication.update -= UpdateHook;
  30. EditorApplication.update += UpdateHook;
  31. }
  32. /// <summary>
  33. /// Draw our flashing text.
  34. /// </summary>
  35. private void OnGUI()
  36. {
  37. Color originalGUIColor = GUI.color;
  38. GUI.color = _flashingTextColor;
  39. GUILayout.Label("My flashing warning message!", EditorStyles.boldLabel);
  40. GUI.color = originalGUIColor;
  41. }
  42. /// <summary>
  43. /// Update() is not automatically called in UnityEditor.Editor controls.
  44. /// We can, however, hook into the EditorApplication.update delegate.
  45. /// </summary>
  46. private void UpdateHook()
  47. {
  48. // Determine the amount of time elapsed since last frame. Remember that
  49. // we are in edit mode, so we cannot use Time.deltaTime.
  50. float timeElapsed = Time.realtimeSinceStartup - _realTimeLastFrame;
  51. _realTimeLastFrame = Time.realtimeSinceStartup;
  52. // Update our flashing text color
  53. UpdateFlashingTextColor(timeElapsed);
  54. }
  55. /// <summary>
  56. /// Updates our flashing text color (for displaying warning messages in
  57. /// the inspector).
  58. /// </summary>
  59. /// <param name="timeElapsed"></param>
  60. private void UpdateFlashingTextColor(float timeElapsed)
  61. {
  62. // Don't fade the text out entirely, just to low opacity, so it can
  63. // flash but still always be easily read.
  64. float minOpacity = .3f;
  65. // Determine how much to change the color based on the time elapsed
  66. float amountToChange = (timeElapsed / FlashingTextCycleDuration) * (1f - minOpacity) * 2;
  67. // Fade the color in or out
  68. if (_fadingColorIn)
  69. _flashingTextColor.a += amountToChange;
  70. else
  71. _flashingTextColor.a -= amountToChange;
  72. // When we've fully faded out, start to fade in, and vice versa
  73. if (_flashingTextColor.a < minOpacity)
  74. {
  75. _flashingTextColor.a = minOpacity;
  76. _fadingColorIn = true;
  77. }
  78. if (_flashingTextColor.a > 1)
  79. {
  80. _flashingTextColor.a = 1;
  81. _fadingColorIn = false;
  82. }
  83. // Repaint our inspector window
  84. Repaint();
  85. }
  86. }
  87. }


Comments are closed here.