277 lines
9.4 KiB
C#
277 lines
9.4 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using DDD.ScriptableObjects;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UI;
|
|
|
|
namespace DDD.Uis.Tycoon
|
|
{
|
|
public class MealKitUi : PopupUi
|
|
{
|
|
[Title("프리팹")]
|
|
[SerializeField]
|
|
private MealKitButton _mealKitButtonPrefab;
|
|
|
|
[Title("컴포넌트")]
|
|
[SerializeField]
|
|
private GameObject _panel;
|
|
|
|
[SerializeField]
|
|
private GameObject _mealKitsLocation;
|
|
|
|
[Title("클래스")]
|
|
[SerializeField]
|
|
private UiEventsController _uiEventsController;
|
|
|
|
[Title("데이터")]
|
|
[SerializeField]
|
|
private int _maxMealKitCount = 6;
|
|
|
|
[Title("실시간 데이터")]
|
|
[SerializeField]
|
|
private List<MealKitButton> _mealKitButtons;
|
|
|
|
private InputAction _interactionEAction;
|
|
private InputAction _cancelAction;
|
|
private InputAction _pressFAction;
|
|
|
|
private void Awake()
|
|
{
|
|
// 더미 데이터 삭제
|
|
foreach (Transform element in _mealKitsLocation.transform)
|
|
{
|
|
if (element)
|
|
{
|
|
Destroy(element.gameObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
EventManager.OnAddedMealKit += SetTodayMenus;
|
|
|
|
_interactionEAction =
|
|
PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.InteractionE);
|
|
_cancelAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.Cancel);
|
|
_pressFAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressF);
|
|
|
|
_mealKitButtons = new List<MealKitButton>(_maxMealKitCount);
|
|
for (int i = 0; i < _maxMealKitCount; i++)
|
|
{
|
|
MealKitButton mealKitButton = Instantiate(_mealKitButtonPrefab, _mealKitsLocation.transform);
|
|
mealKitButton.RegisterButtonListener(() => OnClickedMealKit(mealKitButton));
|
|
_mealKitButtons.Add(mealKitButton);
|
|
}
|
|
|
|
_panel.SetActive(false);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
EventManager.OnAddedMealKit -= SetTodayMenus;
|
|
}
|
|
|
|
private void OnClickedMealKit(MealKitButton mealKitButton)
|
|
{
|
|
if (mealKitButton.CanInteraction())
|
|
{
|
|
CraftRecipeData newCraftRecipeData = new CraftRecipeData(mealKitButton.CraftRecipeData);
|
|
EventManager.InvokePickupMealKit(newCraftRecipeData);
|
|
mealKitButton.PickupMealKit();
|
|
Close();
|
|
}
|
|
}
|
|
|
|
public bool CanOpen()
|
|
{
|
|
return _mealKitButtons.Any(mealKitButton => mealKitButton.CanInteraction());
|
|
}
|
|
|
|
public override void Open()
|
|
{
|
|
base.Open();
|
|
_panel.SetActive(true);
|
|
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.TycoonUi);
|
|
|
|
SortMealKitButtons();
|
|
|
|
_uiEventsController.SetSelectObject(_mealKitButtons[0].gameObject);
|
|
EventSystem.current.SetSelectedGameObject(_uiEventsController.SelectObject);
|
|
}
|
|
|
|
public void OnClose(InputAction.CallbackContext context)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
public override void Close()
|
|
{
|
|
_panel.SetActive(false);
|
|
base.Close();
|
|
|
|
if (PopupUiController.IsPopupListEmpty() || !PopupUiController.IsPausedPopupList())
|
|
{
|
|
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.Tycoon);
|
|
}
|
|
}
|
|
|
|
public override void EnableInput()
|
|
{
|
|
_interactionEAction.performed += OnInteractionE;
|
|
_cancelAction.performed += OnClose;
|
|
_pressFAction.performed += OnClose;
|
|
_uiEventsController.EnableAutoNavigate();
|
|
}
|
|
|
|
public override void DisableInput()
|
|
{
|
|
_interactionEAction.performed -= OnInteractionE;
|
|
_cancelAction.performed -= OnClose;
|
|
_pressFAction.performed -= OnClose;
|
|
_uiEventsController.DisableAutoNavigate();
|
|
}
|
|
|
|
private void OnInteractionE(InputAction.CallbackContext context)
|
|
{
|
|
if (!EventSystem.current) return;
|
|
|
|
EventSystem.current.currentSelectedGameObject.GetComponent<Button>()?.onClick.Invoke();
|
|
}
|
|
|
|
private void SetTodayMenus(List<TodayMenu> todayMenus)
|
|
{
|
|
for (int i = 0; i < _maxMealKitCount; i++)
|
|
{
|
|
_mealKitButtons[i].SetMealKit(todayMenus[i].AddedCraftRecipeData, todayMenus[i].AddedCount);
|
|
if (todayMenus[i].AddedCraftRecipeData == null)
|
|
{
|
|
_mealKitButtons[i].HideUi();
|
|
}
|
|
else
|
|
{
|
|
_mealKitButtons[i].ShowUi();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SortMealKitButtons()
|
|
{
|
|
// 1) 임시 리스트에 인터랙션 가능한 버튼만 먼저 담는다(Stable).
|
|
List<MealKitButton> sortedList = new List<MealKitButton>(_mealKitButtons.Count);
|
|
foreach (var mealKitButton in _mealKitButtons)
|
|
{
|
|
if (mealKitButton.CanInteraction())
|
|
{
|
|
sortedList.Add(mealKitButton);
|
|
}
|
|
}
|
|
|
|
// 2) 그 다음 인터랙션 불가능한 버튼들을 뒤에 붙인다.
|
|
foreach (var mealKitButton in _mealKitButtons)
|
|
{
|
|
if (!mealKitButton.CanInteraction())
|
|
{
|
|
sortedList.Add(mealKitButton);
|
|
}
|
|
}
|
|
|
|
// 3) 재배치한 리스트를 원본 리스트에 반영
|
|
_mealKitButtons = sortedList;
|
|
|
|
// 4) 실제 UI 계층(트랜스폼) 순서도 변경하여 GridLayoutGroup이 의도한 순서로 그리도록 설정
|
|
for (int i = 0; i < _mealKitButtons.Count; i++)
|
|
{
|
|
// i번째 순서대로 형제 인덱스(Sibling Index)를 지정
|
|
_mealKitButtons[i].transform.SetSiblingIndex(i);
|
|
}
|
|
|
|
// 5) 정렬 이후, 내비게이션도 재설정 (정렬 순서가 바뀌었으므로)
|
|
SetNavigationMealKitButtons();
|
|
}
|
|
|
|
private bool IsButtonValid(MealKitButton mealKitButton)
|
|
{
|
|
return mealKitButton != null
|
|
&& mealKitButton.gameObject.activeInHierarchy
|
|
&& mealKitButton.Button != null
|
|
&& mealKitButton.Button.interactable;
|
|
}
|
|
|
|
private void SetNavigationMealKitButtons()
|
|
{
|
|
int columnCount = 3;
|
|
int count = _mealKitButtons.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
MealKitButton currentMealKit = _mealKitButtons[i];
|
|
Button currentButton = currentMealKit.Button;
|
|
|
|
// 새로운 Navigation 객체 생성 및 Explicit 모드 설정
|
|
Navigation nav = new Navigation { mode = Navigation.Mode.Explicit };
|
|
|
|
// 현재 버튼이 비활성(혹은 인터랙션 불가능)하면 내비게이션 항목은 모두 null 처리
|
|
if (!IsButtonValid(currentMealKit))
|
|
{
|
|
currentButton.navigation = nav; // 모든 방향 null
|
|
continue;
|
|
}
|
|
|
|
// 상(Up) 이웃 버튼: 인덱스 i - columnCount
|
|
int upIndex = i - columnCount;
|
|
if (upIndex >= 0 && IsButtonValid(_mealKitButtons[upIndex]))
|
|
{
|
|
nav.selectOnUp = _mealKitButtons[upIndex].Button;
|
|
}
|
|
else
|
|
{
|
|
nav.selectOnUp = null;
|
|
}
|
|
|
|
// 하(Down) 이웃 버튼: 인덱스 i + columnCount
|
|
int downIndex = i + columnCount;
|
|
if (downIndex < count && IsButtonValid(_mealKitButtons[downIndex]))
|
|
{
|
|
nav.selectOnDown = _mealKitButtons[downIndex].Button;
|
|
}
|
|
else
|
|
{
|
|
nav.selectOnDown = null;
|
|
}
|
|
|
|
// 좌(Left) 이웃 버튼: 인덱스 i - 1 (같은 행인지 체크)
|
|
int leftIndex = i - 1;
|
|
if (leftIndex >= 0
|
|
&& (i / columnCount == leftIndex / columnCount)
|
|
&& IsButtonValid(_mealKitButtons[leftIndex]))
|
|
{
|
|
nav.selectOnLeft = _mealKitButtons[leftIndex].Button;
|
|
}
|
|
else
|
|
{
|
|
nav.selectOnLeft = null;
|
|
}
|
|
|
|
// 우(Right) 이웃 버튼: 인덱스 i + 1 (같은 행인지 체크)
|
|
int rightIndex = i + 1;
|
|
if (rightIndex < count
|
|
&& (i / columnCount == rightIndex / columnCount)
|
|
&& IsButtonValid(_mealKitButtons[rightIndex]))
|
|
{
|
|
nav.selectOnRight = _mealKitButtons[rightIndex].Button;
|
|
}
|
|
else
|
|
{
|
|
nav.selectOnRight = null;
|
|
}
|
|
|
|
// 최종 Navigation 할당
|
|
currentButton.navigation = nav;
|
|
}
|
|
}
|
|
}
|
|
} |