using System.Collections; using UnityEngine; using UnityEngine.EventSystems; // IPointerEnterHandler, IPointerExitHandler 인터페이스 사용 using UnityEngine.UI; // Selectable 컴포넌트 사용 (버튼 등의 상호작용 가능 여부 확인) namespace UVC.UI.Tooltip { /// /// UI 요소에 부착하여 마우스 오버 시 툴팁을 표시하고 마우스 아웃 시 툴팁을 숨기는 기능을 제공합니다. /// TooltipManager와 함께 작동하며, 마우스 이벤트 감지 후 TooltipManager에 툴팁 관리를 위임합니다. /// /// 사용 방법: /// 1. 툴팁을 표시하고자 하는 UI 요소(예: Button, Image 등)에 이 컴포넌트를 추가합니다. /// 2. Inspector 창이나 코드를 통해 'Tooltip' 프로퍼티에 표시할 텍스트 또는 다국어 키를 설정합니다. /// 3. TooltipManager가 초기화되어 있어야 하며, 이 핸들러의 액션들을 TooltipManager의 메서드에 연결해야 합니다. /// (일반적으로 다른 관리 클래스(예: ToolbarView)에서 이 연결을 수행합니다.) /// /// 예시 (ToolbarView.cs에서의 설정 부분): /// /// // ... ToolbarView.cs 내에서 버튼 생성 시 ... /// GameObject buttonGameObject = Instantiate(buttonPrefab); /// TooltipHandler tooltipHandler = buttonGameObject.AddComponent(); /// tooltipHandler.Tooltip = "my_tooltip_key"; // 표시할 툴팁 내용 또는 다국어 키 /// /// // TooltipManager의 메서드와 연결 /// if (TooltipManager.Instance != null && TooltipManager.Instance.IsInitialized) /// { /// tooltipHandler.OnPointerEnterAction = TooltipManager.Instance.HandlePointerEnter; /// tooltipHandler.OnPointerExitAction = TooltipManager.Instance.HandlePointerExit; /// } /// /// public class TooltipHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { /// /// 마우스 포인터가 UI 요소에 진입했을 때 호출될 액션입니다. /// TooltipManager.Instance.HandlePointerEnter 메서드에 연결됩니다. /// 첫 번째 string 매개변수는 툴팁 내용(또는 키), 두 번째 Vector3는 마우스 위치입니다. /// public System.Action OnPointerEnterAction; /// /// 마우스 포인터가 UI 요소에서 벗어났을 때 호출될 액션입니다. /// TooltipManager.Instance.HandlePointerExit 메서드에 연결됩니다. /// public System.Action OnPointerExitAction; /// /// 이 UI 요소에 표시될 툴팁의 내용 또는 다국어 키입니다. /// Inspector에서 직접 설정하거나 코드로 할당할 수 있습니다. /// /// /// /// TooltipHandler handler = myButton.GetComponent(); /// if (handler != null) /// { /// handler.Tooltip = "버튼_설명_키"; // 다국어 키 사용 /// // 또는 handler.Tooltip = "이 버튼은 저장 기능을 수행합니다."; // 직접 텍스트 사용 /// } /// /// public string Tooltip { get; set; } private Coroutine _showTooltipCoroutine; // 툴팁 표시 지연을 위한 코루틴 참조 private const float TooltipDelay = 0.5f; // 툴팁 표시까지의 지연 시간 (초 단위) /// /// 마우스 포인터가 이 UI 요소의 영역 안으로 들어왔을 때 호출됩니다. (IPointerEnterHandler 인터페이스 구현) /// 설정된 Tooltip 내용이 있고, 연결된 Selectable 컴포넌트가 상호작용 가능 상태일 때만 작동합니다. /// 지정된 지연 시간(TooltipDelay) 후에 OnPointerEnterAction을 호출하여 툴팁 표시를 요청합니다. /// /// 포인터 이벤트 데이터입니다. public void OnPointerEnter(PointerEventData eventData) { // 툴팁 내용이 있고, 이 게임오브젝트에 Selectable 컴포넌트가 있거나 없거나, 있다면 interactable 상태일 때만 Selectable selectable = gameObject.GetComponent(); if (!string.IsNullOrEmpty(Tooltip) && (selectable == null || selectable.interactable)) { // 이전에 실행 중이던 코루틴이 있다면 중지 (빠르게 들어왔다 나갔다 반복하는 경우 대비) if (_showTooltipCoroutine != null) { StopCoroutine(_showTooltipCoroutine); } // 새 코루틴 시작하여 지연 후 툴팁 표시 _showTooltipCoroutine = StartCoroutine(ShowTooltipAfterDelayCoroutine(Tooltip, Input.mousePosition)); } } /// /// 지정된 시간(TooltipDelay)만큼 대기한 후, OnPointerEnterAction을 호출하여 툴팁 표시를 요청하는 코루틴입니다. /// /// 표시할 툴팁 내용 또는 다국어 키입니다. /// 현재 마우스 포인터의 화면 좌표입니다. private IEnumerator ShowTooltipAfterDelayCoroutine(string tooltipKey, Vector3 mousePosition) { yield return new WaitForSeconds(TooltipDelay); // 지정된 시간만큼 대기 _showTooltipCoroutine = null; // 코루틴 완료 후 참조 null 처리 OnPointerEnterAction?.Invoke(tooltipKey, mousePosition); // 연결된 액션 호출 (TooltipManager.HandlePointerEnter) } /// /// 마우스 포인터가 이 UI 요소의 영역 밖으로 나갔을 때 호출됩니다. (IPointerExitHandler 인터페이스 구현) /// 실행 중인 툴팁 표시 코루틴이 있다면 중지하고, OnPointerExitAction을 호출하여 툴팁 숨김을 요청합니다. /// /// 포인터 이벤트 데이터입니다. public void OnPointerExit(PointerEventData eventData) { // 실행 중인 툴팁 표시 코루틴이 있다면 중지 (마우스가 나가면 지연 중이던 툴팁 표시 취소) if (_showTooltipCoroutine != null) { StopCoroutine(_showTooltipCoroutine); _showTooltipCoroutine = null; } OnPointerExitAction?.Invoke(); // 연결된 액션 호출 (TooltipManager.HandlePointerExit) } /// /// 이 MonoBehaviour가 비활성화될 때 호출됩니다. /// 실행 중인 코루틴이 있다면 정리합니다. /// private void OnDisable() { if (_showTooltipCoroutine != null) { StopCoroutine(_showTooltipCoroutine); _showTooltipCoroutine = null; } // 만약 OnPointerExitAction이 즉시 호출되어야 한다면 아래 코드 추가 // OnPointerExitAction?.Invoke(); } /// /// 이 MonoBehaviour가 파괴될 때 호출됩니다. /// 실행 중인 코루틴이 있다면 정리합니다. /// private void OnDestroy() { if (_showTooltipCoroutine != null) { StopCoroutine(_showTooltipCoroutine); _showTooltipCoroutine = null; } // OnPointerEnterAction 및 OnPointerExitAction 참조 해제 (필요 시) OnPointerEnterAction = null; OnPointerExitAction = null; } } }