using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using UVC.Core; // SingletonScene을 사용하기 위함 using UVC.Locale; using UVC.Pool; // GameObjectPool을 사용하기 위함 namespace UVC.UI.Menu { /// /// 컨텍스트 메뉴의 표시와 관리를 총괄하는 싱글톤 클래스입니다. /// SingletonScene을 상속받아 해당 씬 내에서 유일한 인스턴스를 보장합니다. /// 이 매니저는 코드 기반으로 동적으로 메뉴를 생성하고 표시하는 데 사용됩니다. /// /// /// 사용 예시: 플레이어 캐릭터를 클릭했을 때 상호작용 메뉴를 표시하는 경우 /// /// // 1. 메뉴 항목을 클릭했을 때 실행될 동작을 정의하는 Command 클래스를 구현합니다. /// public class LogCommand : ICommand /// { /// public void Execute(object parameter) /// { /// if (parameter != null) /// { /// Debug.Log("명령 실행: " + parameter.ToString()); /// } /// else /// { /// Debug.Log("명령이 파라미터 없이 실행되었습니다."); /// } /// } /// } /// /// // 2. 메뉴를 표시할 스크립트(예: PlayerInteraction.cs)를 작성합니다. /// public class PlayerInteraction : MonoBehaviour /// { /// void Update() /// { /// // 이 게임 오브젝트가 마우스 오른쪽 버튼으로 클릭되면 메뉴를 표시합니다. /// if (Input.GetMouseButtonDown(1)) /// { /// // Raycast 등으로 이 오브젝트가 클릭되었는지 확인하는 로직이 필요합니다. /// // 여기서는 설명을 위해 바로 호출합니다. /// ShowPlayerMenu(Input.mousePosition); /// } /// } /// /// public void ShowPlayerMenu(Vector2 screenPosition) /// { /// // 3. 메뉴에 표시할 항목 리스트를 동적으로 생성합니다. /// var menuItems = new List /// { /// // ContextMenuItemData 생성자를 사용하여 각 메뉴 항목을 정의합니다. /// // 생성자: (itemId, displayName, command, commandParameter) /// new ContextMenuItemData("player_attack", "공격", new LogCommand(), "플레이어가 '공격'을 선택했습니다."), /// new ContextMenuItemData("player_talk", "대화", new LogCommand(), "플레이어가 '대화'를 선택했습니다."), /// new ContextMenuItemData(isSeparator: true), // 구분선 추가 /// new ContextMenuItemData("player_inspect", "조사", new LogCommand(), "플레이어가 '조사'를 선택했습니다.") /// }; /// /// // 4. ContextMenuManager 싱글톤 인스턴스를 통해 메뉴를 표시합니다. /// ContextMenuManager.Instance.ShowMenu(menuItems, screenPosition); /// } /// } /// /// 참고: /// - `ContextMenuTrigger` 컴포넌트를 사용하면 Inspector에서 정적으로 메뉴를 설정할 수도 있습니다. /// - `DisplayName`에는 다국어 처리를 위한 키 값을 사용할 수 있습니다. (예: "menu_attack") /// public class ContextMenuManager : SingletonScene { [Header("프리팹 설정")] [SerializeField] [Tooltip("컨텍스트 메뉴의 배경이 되는 Panel 프리팹입니다.")] private GameObject contextMenuPrefab; [SerializeField] [Tooltip("컨텍스트 메뉴의 각 항목으로 사용될 Button 프리팹입니다.")] private GameObject contextMenuItemPrefab; [SerializeField] [Tooltip("컨텍스트 메뉴의 구분선으로 사용될 UI 프리팹입니다.")] private GameObject contextMenuSeparatorPrefab; [Header("캔버스 설정")] [SerializeField] [Tooltip("UI가 그려질 최상위 Canvas입니다. 메뉴가 다른 UI 위에 그려지도록 합니다.")] private Canvas mainCanvas; // 현재 활성화된 컨텍스트 메뉴의 RectTransform private RectTransform _activeMenuRect; // 메뉴 항목들을 담을 부모 객체 private Transform _menuItemContainer; // 메뉴 항목 버튼들을 관리하기 위한 오브젝트 풀 private ItemPool