DebugLogPopup.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using UnityEngine.EventSystems;
  4. using System.Collections;
  5. // Manager class for the debug popup
  6. namespace IngameDebugConsole
  7. {
  8. public class DebugLogPopup : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
  9. {
  10. private RectTransform popupTransform;
  11. // Dimensions of the popup divided by 2
  12. private Vector2 halfSize;
  13. // Background image that will change color to indicate an alert
  14. private Image backgroundImage;
  15. // Canvas group to modify visibility of the popup
  16. private CanvasGroup canvasGroup;
  17. #pragma warning disable 0649
  18. [SerializeField]
  19. private DebugLogManager debugManager;
  20. [SerializeField]
  21. private Text newInfoCountText;
  22. [SerializeField]
  23. private Text newWarningCountText;
  24. [SerializeField]
  25. private Text newErrorCountText;
  26. [SerializeField]
  27. private Color alertColorInfo;
  28. [SerializeField]
  29. private Color alertColorWarning;
  30. [SerializeField]
  31. private Color alertColorError;
  32. #pragma warning restore 0649
  33. // Number of new debug entries since the log window has been closed
  34. private int newInfoCount = 0, newWarningCount = 0, newErrorCount = 0;
  35. private Color normalColor;
  36. private bool isPopupBeingDragged = false;
  37. private Vector2 normalizedPosition;
  38. // Coroutines for simple code-based animations
  39. private IEnumerator moveToPosCoroutine = null;
  40. private void Awake()
  41. {
  42. popupTransform = (RectTransform) transform;
  43. backgroundImage = GetComponent<Image>();
  44. canvasGroup = GetComponent<CanvasGroup>();
  45. normalColor = backgroundImage.color;
  46. halfSize = popupTransform.sizeDelta * 0.5f;
  47. Vector2 pos = popupTransform.anchoredPosition;
  48. if( pos.x != 0f || pos.y != 0f )
  49. normalizedPosition = pos.normalized; // Respect the initial popup position set in the prefab
  50. else
  51. normalizedPosition = new Vector2( 0.5f, 0f ); // Right edge by default
  52. }
  53. public void NewLogsArrived( int newInfo, int newWarning, int newError )
  54. {
  55. if( newInfo > 0 )
  56. {
  57. newInfoCount += newInfo;
  58. newInfoCountText.text = newInfoCount.ToString();
  59. }
  60. if( newWarning > 0 )
  61. {
  62. newWarningCount += newWarning;
  63. newWarningCountText.text = newWarningCount.ToString();
  64. }
  65. if( newError > 0 )
  66. {
  67. newErrorCount += newError;
  68. newErrorCountText.text = newErrorCount.ToString();
  69. }
  70. if( newErrorCount > 0 )
  71. backgroundImage.color = alertColorError;
  72. else if( newWarningCount > 0 )
  73. backgroundImage.color = alertColorWarning;
  74. else
  75. backgroundImage.color = alertColorInfo;
  76. }
  77. private void Reset()
  78. {
  79. newInfoCount = 0;
  80. newWarningCount = 0;
  81. newErrorCount = 0;
  82. newInfoCountText.text = "0";
  83. newWarningCountText.text = "0";
  84. newErrorCountText.text = "0";
  85. backgroundImage.color = normalColor;
  86. }
  87. // A simple smooth movement animation
  88. private IEnumerator MoveToPosAnimation( Vector2 targetPos )
  89. {
  90. float modifier = 0f;
  91. Vector2 initialPos = popupTransform.anchoredPosition;
  92. while( modifier < 1f )
  93. {
  94. modifier += 4f * Time.unscaledDeltaTime;
  95. popupTransform.anchoredPosition = Vector2.Lerp( initialPos, targetPos, modifier );
  96. yield return null;
  97. }
  98. }
  99. // Popup is clicked
  100. public void OnPointerClick( PointerEventData data )
  101. {
  102. // Hide the popup and show the log window
  103. if( !isPopupBeingDragged )
  104. debugManager.ShowLogWindow();
  105. }
  106. // Hides the log window and shows the popup
  107. public void Show()
  108. {
  109. canvasGroup.interactable = true;
  110. canvasGroup.blocksRaycasts = true;
  111. canvasGroup.alpha = 1f;
  112. // Reset the counters
  113. Reset();
  114. // Update position in case resolution was changed while the popup was hidden
  115. UpdatePosition( true );
  116. }
  117. // Hide the popup
  118. public void Hide()
  119. {
  120. canvasGroup.interactable = false;
  121. canvasGroup.blocksRaycasts = false;
  122. canvasGroup.alpha = 0f;
  123. isPopupBeingDragged = false;
  124. }
  125. public void OnBeginDrag( PointerEventData data )
  126. {
  127. isPopupBeingDragged = true;
  128. // If a smooth movement animation is in progress, cancel it
  129. if( moveToPosCoroutine != null )
  130. {
  131. StopCoroutine( moveToPosCoroutine );
  132. moveToPosCoroutine = null;
  133. }
  134. }
  135. // Reposition the popup
  136. public void OnDrag( PointerEventData data )
  137. {
  138. Vector2 localPoint;
  139. if( RectTransformUtility.ScreenPointToLocalPointInRectangle( debugManager.canvasTR, data.position, data.pressEventCamera, out localPoint ) )
  140. popupTransform.anchoredPosition = localPoint;
  141. }
  142. // Smoothly translate the popup to the nearest edge
  143. public void OnEndDrag( PointerEventData data )
  144. {
  145. isPopupBeingDragged = false;
  146. UpdatePosition( false );
  147. }
  148. public void UpdatePosition( bool immediately )
  149. {
  150. Vector2 canvasSize = debugManager.canvasTR.rect.size;
  151. float canvasWidth = canvasSize.x;
  152. float canvasHeight = canvasSize.y;
  153. // normalizedPosition allows us to glue the popup to a specific edge of the screen. It becomes useful when
  154. // the popup is at the right edge and we switch from portrait screen orientation to landscape screen orientation.
  155. // Without normalizedPosition, popup could jump to bottom or top edges instead of staying at the right edge
  156. Vector2 pos = immediately ? new Vector2( normalizedPosition.x * canvasWidth, normalizedPosition.y * canvasHeight ) : popupTransform.anchoredPosition;
  157. // Find distances to all four edges
  158. float distToLeft = canvasWidth * 0.5f + pos.x;
  159. float distToRight = canvasWidth - distToLeft;
  160. float distToBottom = canvasHeight * 0.5f + pos.y;
  161. float distToTop = canvasHeight - distToBottom;
  162. float horDistance = Mathf.Min( distToLeft, distToRight );
  163. float vertDistance = Mathf.Min( distToBottom, distToTop );
  164. // Find the nearest edge's coordinates
  165. if( horDistance < vertDistance )
  166. {
  167. if( distToLeft < distToRight )
  168. pos = new Vector2( canvasWidth * -0.5f + halfSize.x, pos.y );
  169. else
  170. pos = new Vector2( canvasWidth * 0.5f - halfSize.x, pos.y );
  171. pos.y = Mathf.Clamp( pos.y, canvasHeight * -0.5f + halfSize.y, canvasHeight * 0.5f - halfSize.y );
  172. }
  173. else
  174. {
  175. if( distToBottom < distToTop )
  176. pos = new Vector2( pos.x, canvasHeight * -0.5f + halfSize.y );
  177. else
  178. pos = new Vector2( pos.x, canvasHeight * 0.5f - halfSize.y );
  179. pos.x = Mathf.Clamp( pos.x, canvasWidth * -0.5f + halfSize.x, canvasWidth * 0.5f - halfSize.x );
  180. }
  181. normalizedPosition.Set( pos.x / canvasWidth, pos.y / canvasHeight );
  182. // If another smooth movement animation is in progress, cancel it
  183. if( moveToPosCoroutine != null )
  184. {
  185. StopCoroutine( moveToPosCoroutine );
  186. moveToPosCoroutine = null;
  187. }
  188. if( immediately )
  189. popupTransform.anchoredPosition = pos;
  190. else
  191. {
  192. // Smoothly translate the popup to the specified position
  193. moveToPosCoroutine = MoveToPosAnimation( pos );
  194. StartCoroutine( moveToPosCoroutine );
  195. }
  196. }
  197. }
  198. }