BaseClickBlocker.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using UnityEngine;
  2. using System.Collections;
  3. /// <summary>
  4. /// Base class for UI components that need to block map clicks.
  5. /// Handles the common click blocking functionality including registration,
  6. /// flag management, and coroutine handling.
  7. /// </summary>
  8. public abstract class BaseClickBlocker : MonoBehaviour, IClickBlocker
  9. {
  10. /// <summary>
  11. /// Flag to prevent map clicks when UI handles them
  12. /// </summary>
  13. [System.NonSerialized]
  14. protected bool recentlyHandledClick = false;
  15. /// <summary>
  16. /// Whether this UI is currently visible and should block clicks
  17. /// </summary>
  18. protected virtual bool IsUIVisible => true;
  19. /// <summary>
  20. /// Auto-register/unregister with ClickManager
  21. /// </summary>
  22. protected virtual void OnEnable() => ClickManager.Instance?.RegisterClickBlocker(this);
  23. protected virtual void OnDisable() => ClickManager.Instance?.UnregisterClickBlocker(this);
  24. /// <summary>
  25. /// Abstract method that each UI component must implement to define its specific blocking logic
  26. /// </summary>
  27. public abstract bool IsBlockingClick(Vector2 screenPosition);
  28. /// <summary>
  29. /// Sets a temporary flag to block travel system clicks when UI handles a click event.
  30. /// This is much more reliable than trying to calculate coordinates manually.
  31. /// Call this from your UI event handlers (MouseDownEvent, ClickEvent, etc.)
  32. /// </summary>
  33. protected void SetClickFlag()
  34. {
  35. recentlyHandledClick = true;
  36. Debug.Log($"🚫 {GetType().Name}: Click flag SET - blocking map clicks");
  37. // Also immediately stop any current coroutine to prevent premature reset
  38. StopAllCoroutines();
  39. // Reset the flag after a longer delay to ensure we catch same-frame clicks
  40. StartCoroutine(ResetClickFlag());
  41. }
  42. /// <summary>
  43. /// Resets the click blocking flag after a short delay
  44. /// </summary>
  45. private IEnumerator ResetClickFlag()
  46. {
  47. // Wait longer to ensure we block clicks that happen in the same frame
  48. yield return new WaitForEndOfFrame(); // Wait one frame
  49. yield return new WaitForEndOfFrame(); // Wait another frame
  50. yield return new WaitForSeconds(0.1f); // Wait additional time to be extra safe
  51. recentlyHandledClick = false;
  52. Debug.Log($"🔓 {GetType().Name}: Click flag reset - map clicks allowed again");
  53. }
  54. /// <summary>
  55. /// Helper method to check if a recent UI click should block the current check
  56. /// Use this as the first check in your IsBlockingClick implementation
  57. /// </summary>
  58. protected bool ShouldBlockDueToRecentClick()
  59. {
  60. if (recentlyHandledClick)
  61. {
  62. Debug.Log($"🚫 {GetType().Name}: Blocking click due to recent UI interaction");
  63. return true;
  64. }
  65. return false;
  66. }
  67. /// <summary>
  68. /// Helper method to check if UI is visible before doing coordinate checks
  69. /// Use this as the second check in your IsBlockingClick implementation
  70. /// </summary>
  71. protected bool ShouldSkipDueToInvisibleUI()
  72. {
  73. if (!IsUIVisible)
  74. {
  75. return true; // Skip blocking if UI is not visible
  76. }
  77. return false;
  78. }
  79. }