ClickManager.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. /// <summary>
  4. /// Global click manager that handles click propagation between UI elements and the game world.
  5. /// UI components register themselves as click blockers to prevent map interaction when appropriate.
  6. /// </summary>
  7. public class ClickManager : MonoBehaviour
  8. {
  9. private static ClickManager _instance;
  10. public static ClickManager Instance
  11. {
  12. get
  13. {
  14. if (_instance == null)
  15. {
  16. // Try to find existing instance first
  17. _instance = FindFirstObjectByType<ClickManager>();
  18. if (_instance == null)
  19. {
  20. // Create a new ClickManager GameObject if none exists
  21. GameObject clickManagerObj = new GameObject("ClickManager");
  22. _instance = clickManagerObj.AddComponent<ClickManager>();
  23. DontDestroyOnLoad(clickManagerObj);
  24. Debug.Log("✅ ClickManager auto-created");
  25. }
  26. }
  27. return _instance;
  28. }
  29. }
  30. private readonly HashSet<IClickBlocker> clickBlockers = new HashSet<IClickBlocker>();
  31. [Header("Debug")]
  32. public bool showDebugLogs = false;
  33. void Awake()
  34. {
  35. if (_instance == null)
  36. {
  37. _instance = this;
  38. DontDestroyOnLoad(gameObject);
  39. if (showDebugLogs)
  40. {
  41. Debug.Log("✅ ClickManager instance created");
  42. }
  43. }
  44. else
  45. {
  46. if (showDebugLogs)
  47. {
  48. Debug.LogWarning("Multiple ClickManager instances found. Destroying this one.");
  49. }
  50. Destroy(gameObject);
  51. }
  52. }
  53. /// <summary>
  54. /// Registers a UI component that can block clicks.
  55. /// </summary>
  56. public void RegisterClickBlocker(IClickBlocker blocker)
  57. {
  58. if (blocker != null)
  59. {
  60. clickBlockers.Add(blocker);
  61. if (showDebugLogs)
  62. {
  63. Debug.Log($"📝 Registered click blocker: {blocker.GetType().Name}");
  64. }
  65. }
  66. }
  67. /// <summary>
  68. /// Unregisters a UI component.
  69. /// </summary>
  70. public void UnregisterClickBlocker(IClickBlocker blocker)
  71. {
  72. if (blocker != null)
  73. {
  74. clickBlockers.Remove(blocker);
  75. if (showDebugLogs)
  76. {
  77. Debug.Log($"❌ Unregistered click blocker: {blocker.GetType().Name}");
  78. }
  79. }
  80. }
  81. /// <summary>
  82. /// Checks if any registered UI component is blocking clicks at the given screen position.
  83. /// </summary>
  84. public bool IsClickBlocked(Vector2 screenPosition)
  85. {
  86. foreach (var blocker in clickBlockers)
  87. {
  88. if (blocker != null && blocker.IsBlockingClick(screenPosition))
  89. {
  90. if (showDebugLogs)
  91. {
  92. Debug.Log($"🚫 Click blocked by: {blocker.GetType().Name} at position {screenPosition}");
  93. }
  94. return true;
  95. }
  96. }
  97. if (showDebugLogs)
  98. {
  99. Debug.Log($"✅ Click allowed at position {screenPosition} (checked {clickBlockers.Count} blockers)");
  100. }
  101. return false;
  102. }
  103. /// <summary>
  104. /// Gets the number of currently registered click blockers (for debugging)
  105. /// </summary>
  106. public int GetRegisteredBlockersCount()
  107. {
  108. return clickBlockers.Count;
  109. }
  110. /// <summary>
  111. /// Lists all registered click blockers (for debugging)
  112. /// </summary>
  113. public void ListRegisteredBlockers()
  114. {
  115. Debug.Log($"📋 Registered Click Blockers ({clickBlockers.Count}):");
  116. foreach (var blocker in clickBlockers)
  117. {
  118. Debug.Log($" - {blocker?.GetType().Name ?? "NULL"}");
  119. }
  120. }
  121. }