CLICK_MANAGEMENT_REFACTORIZATION_SUMMARY.md 5.1 KB

Click Management System Refactorization Summary

Overview

This document summarizes the refactorization of the click management system in the RPG-RougeLiteBatteler project. The goal was to replace the tightly coupled click handling in TeamTravelSystem with a modular, extensible system that allows UI components to handle their own click logic.

Problem with Previous System

The original system in TeamTravelSystem.cs had several issues:

  1. Tight Coupling: Travel system directly referenced and checked multiple UI components (TravelUI, CombatEventPopupUXML)
  2. Hard to Extend: Adding new UI components required modifying the travel system
  3. Violation of Separation of Concerns: Travel system knew too much about UI implementation details
  4. Maintenance Issues: Changes to UI components often required changes to travel system

New Architecture

1. Core Components

IClickBlocker Interface

  • File: Assets/Scripts/UI/IClickBlocker.cs
  • Purpose: Defines contract for UI components that can block clicks
  • Method: bool IsBlockingClick(Vector2 screenPosition)

ClickManager Class

  • File: Assets/Scripts/UI/ClickManager.cs
  • Purpose: Centralized click management system
  • Features:
    • Singleton pattern with auto-creation
    • Registration/unregistration of click blockers
    • Single point to check if clicks should be blocked
    • Debug logging capabilities

2. Updated UI Components

TravelUI Class

  • Changes:
    • Implements IClickBlocker interface
    • Auto-registers/unregisters with ClickManager on Enable/Disable/Destroy
    • IsPointWithinUI() method now delegates to IsBlockingClick()
    • Maintains backward compatibility

CombatEventPopupUXML Class

  • Changes:
    • Implements IClickBlocker interface
    • Auto-registers/unregisters with ClickManager on Enable/Disable/Destroy
    • IsPointWithinUI() method now delegates to IsBlockingClick()
    • Maintains backward compatibility

3. Simplified TeamTravelSystem

TeamTravelSystem Class

  • Changes:
    • Removed direct references to CombatEventPopupUXML
    • Simplified HandleInput() method to use ClickManager.Instance.IsClickBlocked()
    • Removed IsTravelUIBlocking() dependency on combat popup
    • Much cleaner and more maintainable code

Implementation Details

Auto-Registration Pattern

UI components automatically register themselves with the ClickManager:

void OnEnable()
{
    if (ClickManager.Instance != null)
        ClickManager.Instance.RegisterClickBlocker(this);
}

void OnDisable()
{
    if (ClickManager.Instance != null)
        ClickManager.Instance.UnregisterClickBlocker(this);
}

Centralized Click Checking

The travel system now uses a single, clean check:

if (ClickManager.Instance != null && ClickManager.Instance.IsClickBlocked(Input.mousePosition))
{
    return; // Block map interaction
}

Backward Compatibility

Existing code that calls IsPointWithinUI() continues to work as these methods now delegate to the new IsBlockingClick() implementation.

Benefits of New System

  1. Decoupled Architecture: Travel system no longer knows about specific UI components
  2. Easy Extension: New UI components just implement IClickBlocker and auto-register
  3. Single Responsibility: Each component handles its own click logic
  4. Centralized Control: One place to check and debug click blocking
  5. Maintainable: Changes to UI components don't affect travel system
  6. Testable: Components can be tested independently

Usage for New UI Components

To add a new UI component that blocks clicks:

  1. Implement IClickBlocker interface:

    public class MyNewUI : MonoBehaviour, IClickBlocker
    {
    public bool IsBlockingClick(Vector2 screenPosition)
    {
        // Your click detection logic here
        return isVisible && IsWithinBounds(screenPosition);
    }
    }
    
  2. Add registration in lifecycle methods:

    void OnEnable() => ClickManager.Instance?.RegisterClickBlocker(this);
    void OnDisable() => ClickManager.Instance?.UnregisterClickBlocker(this);
    void OnDestroy() => ClickManager.Instance?.UnregisterClickBlocker(this);
    
  3. That's it! The travel system will automatically respect your UI's click blocking.

Testing

A test script ClickManagerTest.cs is provided to verify the system works correctly:

  • Press 'T' key to test ClickManager availability and list registered blockers
  • Click anywhere to see if clicks are blocked or allowed
  • Enable debug info to see detailed logging

Files Modified

  • Assets/Scripts/UI/ClickManager.cs (NEW)
  • Assets/Scripts/UI/IClickBlocker.cs (NEW)
  • Assets/Scripts/UI/ClickManagerTest.cs (NEW)
  • Assets/Scripts/UI/TravelUI.cs (MODIFIED)
  • Assets/Scripts/UI/CombatEventPopupUXML.cs (MODIFIED)
  • Assets/Scripts/Map/TeamTravelSystem.cs (MODIFIED)

Future Improvements

  1. Priority System: Add priority levels for click blockers
  2. Event System: Allow components to subscribe to click events
  3. Area-Based Blocking: Support for partial screen area blocking
  4. Performance Optimization: Cache frequently used bounds calculations
  5. Visual Debug Mode: Show click blocker bounds in scene view