302 lines
9.3 KiB
C#
302 lines
9.3 KiB
C#
using System.Collections.Generic;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using TMPro;
|
|
|
|
namespace Northbound
|
|
{
|
|
/// <summary>
|
|
/// 건설 모드 시 건축 가능한 건물들을 표시하는 퀵슬롯 UI
|
|
/// </summary>
|
|
public class BuildingQuickslotUI : MonoBehaviour
|
|
{
|
|
public static BuildingQuickslotUI Instance { get; private set; }
|
|
|
|
[Header("UI References")]
|
|
[SerializeField] private GameObject quickslotPanel;
|
|
[SerializeField] private Transform slotContainer;
|
|
[SerializeField] private GameObject slotButtonPrefab;
|
|
|
|
[Header("Settings")]
|
|
[SerializeField] private int maxSlots = 8;
|
|
|
|
private List<BuildingSlotButton> slotButtons = new List<BuildingSlotButton>();
|
|
private BuildingPlacement buildingPlacement;
|
|
private int currentSelectedIndex = -1;
|
|
private PlayerInputActions _inputActions;
|
|
private InputAction[] _quickslotActions;
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance != null && Instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
Instance = this;
|
|
|
|
// Input Actions 초기화
|
|
_inputActions = new PlayerInputActions();
|
|
InitializeQuickslotActions();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
EnableQuickslotActions(false); // 초기에는 비활성화
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
DisableQuickslotActions();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
UnsubscribeQuickslotActions();
|
|
_inputActions?.Dispose();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (quickslotPanel != null)
|
|
{
|
|
quickslotPanel.SetActive(false);
|
|
}
|
|
|
|
InitializeSlots();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 퀵슬롯 Input Actions 초기화 및 구독 (직접 참조)
|
|
/// </summary>
|
|
private void InitializeQuickslotActions()
|
|
{
|
|
_quickslotActions = new InputAction[maxSlots];
|
|
|
|
// 수동으로 각 액션 할당
|
|
// Input Actions 에셋에 QuickSlot1~8 액션을 추가했는지 확인하세요
|
|
_quickslotActions[0] = _inputActions.Player.QuickSlot1;
|
|
_quickslotActions[1] = _inputActions.Player.QuickSlot2;
|
|
_quickslotActions[2] = _inputActions.Player.QuickSlot3;
|
|
_quickslotActions[3] = _inputActions.Player.QuickSlot4;
|
|
_quickslotActions[4] = _inputActions.Player.QuickSlot5;
|
|
_quickslotActions[5] = _inputActions.Player.QuickSlot6;
|
|
_quickslotActions[6] = _inputActions.Player.QuickSlot7;
|
|
_quickslotActions[7] = _inputActions.Player.QuickSlot8;
|
|
|
|
// 이벤트 구독
|
|
for (int i = 0; i < _quickslotActions.Length; i++)
|
|
{
|
|
if (_quickslotActions[i] != null)
|
|
{
|
|
int slotIndex = i; // 클로저 캡처를 위한 로컬 변수
|
|
_quickslotActions[i].performed += ctx => OnQuickslotPressed(slotIndex);
|
|
// Debug.Log($"[BuildingQuickslotUI] QuickSlot{i + 1} 액션 바인딩 성공");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"[BuildingQuickslotUI] QuickSlot{i + 1} 액션이 null입니다. Input Actions 에셋을 확인하세요.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 퀵슬롯 액션 구독 해제
|
|
/// </summary>
|
|
private void UnsubscribeQuickslotActions()
|
|
{
|
|
if (_quickslotActions == null) return;
|
|
|
|
for (int i = 0; i < _quickslotActions.Length; i++)
|
|
{
|
|
if (_quickslotActions[i] != null)
|
|
{
|
|
int slotIndex = i;
|
|
_quickslotActions[i].performed -= ctx => OnQuickslotPressed(slotIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 퀵슬롯 액션 활성화
|
|
/// </summary>
|
|
private void EnableQuickslotActions(bool enable)
|
|
{
|
|
if (_quickslotActions == null) return;
|
|
|
|
foreach (var action in _quickslotActions)
|
|
{
|
|
if (action != null)
|
|
{
|
|
if (enable)
|
|
action.Enable();
|
|
else
|
|
action.Disable();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 퀵슬롯 액션 비활성화
|
|
/// </summary>
|
|
private void DisableQuickslotActions()
|
|
{
|
|
EnableQuickslotActions(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 퀵슬롯 키 입력 처리
|
|
/// </summary>
|
|
private void OnQuickslotPressed(int slotIndex)
|
|
{
|
|
// 퀵슬롯이 활성화되어 있고, 유효한 인덱스인 경우만 처리
|
|
if (quickslotPanel != null && quickslotPanel.activeSelf && slotIndex < slotButtons.Count)
|
|
{
|
|
SelectBuilding(slotIndex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// BuildingManager의 건물 목록으로 슬롯 초기화
|
|
/// </summary>
|
|
private void InitializeSlots()
|
|
{
|
|
if (BuildingManager.Instance == null || slotContainer == null || slotButtonPrefab == null)
|
|
{
|
|
Debug.LogWarning("[BuildingQuickslotUI] 필수 컴포넌트가 설정되지 않았습니다.");
|
|
return;
|
|
}
|
|
|
|
// 기존 슬롯 제거
|
|
foreach (var slot in slotButtons)
|
|
{
|
|
if (slot != null)
|
|
Destroy(slot.gameObject);
|
|
}
|
|
slotButtons.Clear();
|
|
|
|
// 건물 목록으로 슬롯 생성 (최대 maxSlots개)
|
|
var buildings = BuildingManager.Instance.availableBuildings;
|
|
int slotCount = Mathf.Min(buildings.Count, maxSlots);
|
|
|
|
for (int i = 0; i < slotCount; i++)
|
|
{
|
|
CreateSlot(buildings[i], i);
|
|
}
|
|
|
|
Debug.Log($"[BuildingQuickslotUI] {slotButtons.Count}개의 건물 슬롯 생성됨");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 개별 슬롯 버튼 생성
|
|
/// </summary>
|
|
private void CreateSlot(BuildingData buildingData, int index)
|
|
{
|
|
GameObject slotObj = Instantiate(slotButtonPrefab, slotContainer);
|
|
BuildingSlotButton slotButton = slotObj.GetComponent<BuildingSlotButton>();
|
|
|
|
if (slotButton != null)
|
|
{
|
|
slotButton.Initialize(buildingData, index, this);
|
|
slotButtons.Add(slotButton);
|
|
|
|
// 핫키 표시 (1-8)
|
|
slotButton.SetHotkeyText((index + 1).ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 건설 모드 활성화 (BuildingPlacement에서 호출)
|
|
/// </summary>
|
|
public void ShowQuickslot(BuildingPlacement placement)
|
|
{
|
|
buildingPlacement = placement;
|
|
|
|
if (quickslotPanel != null)
|
|
{
|
|
quickslotPanel.SetActive(true);
|
|
}
|
|
|
|
// 퀵슬롯 입력 활성화
|
|
EnableQuickslotActions(true);
|
|
|
|
// 기본 선택 (첫 번째 건물)
|
|
if (slotButtons.Count > 0)
|
|
{
|
|
SelectBuilding(0);
|
|
}
|
|
|
|
Debug.Log("[BuildingQuickslotUI] 건설 퀵슬롯 표시됨");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 건설 모드 비활성화
|
|
/// </summary>
|
|
public void HideQuickslot()
|
|
{
|
|
if (quickslotPanel != null)
|
|
{
|
|
quickslotPanel.SetActive(false);
|
|
}
|
|
|
|
// 퀵슬롯 입력 비활성화
|
|
DisableQuickslotActions();
|
|
|
|
buildingPlacement = null;
|
|
currentSelectedIndex = -1;
|
|
|
|
// 모든 슬롯 선택 해제
|
|
foreach (var slot in slotButtons)
|
|
{
|
|
if (slot != null)
|
|
slot.SetSelected(false);
|
|
}
|
|
|
|
Debug.Log("[BuildingQuickslotUI] 건설 퀵슬롯 숨김");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 건물 선택 (슬롯 버튼 클릭 또는 핫키)
|
|
/// </summary>
|
|
public void SelectBuilding(int index)
|
|
{
|
|
if (index < 0 || index >= slotButtons.Count)
|
|
return;
|
|
|
|
// 이전 선택 해제
|
|
if (currentSelectedIndex >= 0 && currentSelectedIndex < slotButtons.Count)
|
|
{
|
|
slotButtons[currentSelectedIndex].SetSelected(false);
|
|
}
|
|
|
|
// 새로운 선택
|
|
currentSelectedIndex = index;
|
|
slotButtons[index].SetSelected(true);
|
|
|
|
// BuildingPlacement에 알림
|
|
if (buildingPlacement != null)
|
|
{
|
|
buildingPlacement.SetSelectedBuilding(index);
|
|
}
|
|
|
|
Debug.Log($"[BuildingQuickslotUI] 건물 선택됨: {slotButtons[index].GetBuildingName()} (인덱스: {index})");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 현재 선택된 건물 인덱스
|
|
/// </summary>
|
|
public int GetSelectedIndex()
|
|
{
|
|
return currentSelectedIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 슬롯 개수 반환
|
|
/// </summary>
|
|
public int GetSlotCount()
|
|
{
|
|
return slotButtons.Count;
|
|
}
|
|
}
|
|
} |