374 lines
13 KiB
C#
374 lines
13 KiB
C#
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using System.Collections.Generic;
|
||
|
||
public class PlayerCursorUI : MonoBehaviour
|
||
{
|
||
public GameManager gameManager;
|
||
public Canvas parentCanvas; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
public int playerId = 1; // 1 <20><><EFBFBD> 2 (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||
|
||
private List<Button> buttons = new List<Button>();
|
||
private int currentIndex = 0;
|
||
|
||
private ButtonPinMapping upKey;
|
||
private ButtonPinMapping downKey;
|
||
private ButtonPinMapping leftKey;
|
||
private ButtonPinMapping rightKey;
|
||
private ButtonPinMapping selectKey;
|
||
|
||
private bool useJoystick = false;
|
||
|
||
// Cache UIManager for active panel tracking
|
||
private UIManager uiManager;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
private bool panelChanged = false;
|
||
|
||
// 2D grid navigation state (используется когда активный экран имеет ButtonGridLayout)
|
||
private int gridRow = 0;
|
||
private int gridCol = 0;
|
||
|
||
void Start()
|
||
{
|
||
var player = GetComponentInParent<Player>();
|
||
if (player != null)
|
||
playerId = player.PlayerId;
|
||
|
||
EnsureUIManager();
|
||
|
||
DetectInputDevice();
|
||
BindControls();
|
||
RefreshButtons();
|
||
}
|
||
|
||
void Awake()
|
||
{
|
||
EnsureUIManager();
|
||
}
|
||
|
||
void DetectInputDevice()
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
var joysticks = Input.GetJoystickNames();
|
||
if (joysticks.Length > 0 && !string.IsNullOrEmpty(joysticks[0]))
|
||
useJoystick = true;
|
||
else
|
||
useJoystick = false;
|
||
}
|
||
|
||
void BindControls()
|
||
{
|
||
if (!useJoystick) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
if (playerId == 1)
|
||
{
|
||
upKey = ButtonPinMapping.up1;
|
||
downKey = ButtonPinMapping.down1;
|
||
leftKey = ButtonPinMapping.left1;
|
||
rightKey = ButtonPinMapping.right1;
|
||
selectKey = ButtonPinMapping.action1;
|
||
}
|
||
else
|
||
{
|
||
upKey = ButtonPinMapping.up2;
|
||
downKey = ButtonPinMapping.down2;
|
||
leftKey = ButtonPinMapping.left2;
|
||
rightKey = ButtonPinMapping.right2;
|
||
selectKey = ButtonPinMapping.action2;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void OnEnable()
|
||
{
|
||
if (gameManager != null)
|
||
gameManager.OnInputModeChanged += HandleInputModeChanged;
|
||
|
||
EnsureUIManager();
|
||
if (uiManager != null)
|
||
uiManager.OnPanelChanged += HandlePanelChanged;
|
||
}
|
||
|
||
void OnDisable()
|
||
{
|
||
if (gameManager != null)
|
||
gameManager.OnInputModeChanged -= HandleInputModeChanged;
|
||
|
||
if (uiManager != null)
|
||
uiManager.OnPanelChanged -= HandlePanelChanged;
|
||
}
|
||
|
||
void EnsureUIManager()
|
||
{
|
||
// Prefer UIManager from the associated GameManager
|
||
var candidate = gameManager != null ? gameManager.uiManager : null;
|
||
if (candidate == null)
|
||
candidate = FindObjectOfType<UIManager>();
|
||
|
||
if (candidate == uiManager)
|
||
return;
|
||
|
||
// Rewire event subscription if UIManager instance changed
|
||
if (uiManager != null)
|
||
uiManager.OnPanelChanged -= HandlePanelChanged;
|
||
|
||
uiManager = candidate;
|
||
|
||
if (uiManager != null && isActiveAndEnabled)
|
||
uiManager.OnPanelChanged += HandlePanelChanged;
|
||
}
|
||
|
||
void HandlePanelChanged()
|
||
{
|
||
panelChanged = true;
|
||
}
|
||
|
||
void HandleInputModeChanged(GameManager.InputMode mode)
|
||
{
|
||
if (mode == GameManager.InputMode.UI)
|
||
{
|
||
RefreshButtons();
|
||
}
|
||
else
|
||
{
|
||
ClearHighlight();
|
||
}
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (gameManager == null || gameManager.currentInputMode != GameManager.InputMode.UI)
|
||
return;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (panelChanged)
|
||
{
|
||
RefreshButtons();
|
||
panelChanged = false;
|
||
return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (buttons.Count == 0 || !buttons[currentIndex].gameObject.activeInHierarchy)
|
||
{
|
||
RefreshButtons();
|
||
}
|
||
|
||
if (buttons.Count == 0) return;
|
||
|
||
bool moved = false;
|
||
|
||
// Проверяем есть ли ButtonGridLayout на активном экране.
|
||
// Если активен оверлей — grid не используем: его кнопки не входят в сетку экрана.
|
||
ButtonGridLayout grid = null;
|
||
if (uiManager != null && uiManager.GetActiveOverlay() == null)
|
||
{
|
||
var activeScreen = uiManager.GetActiveScreen();
|
||
if (activeScreen != null)
|
||
grid = activeScreen.GetComponent<ButtonGridLayout>();
|
||
}
|
||
|
||
if (grid != null && grid.RowCount > 0)
|
||
{
|
||
// --- 2D навигация: Up/Down — ряды, Left/Right — столбцы ---
|
||
|
||
// Синхронизируем gridRow/gridCol с текущей кнопкой
|
||
if (grid.TryFindButton(buttons[currentIndex], out int fr, out int fc))
|
||
{ gridRow = fr; gridCol = fc; }
|
||
|
||
if (In.GetButtonDown(upKey))
|
||
{
|
||
gridRow = (gridRow - 1 + grid.RowCount) % grid.RowCount;
|
||
moved = true;
|
||
}
|
||
if (In.GetButtonDown(downKey))
|
||
{
|
||
gridRow = (gridRow + 1) % grid.RowCount;
|
||
moved = true;
|
||
}
|
||
if (In.GetButtonDown(leftKey))
|
||
{
|
||
bool overlayActive = uiManager != null && uiManager.GetActiveOverlay() != null;
|
||
if (gameManager.currentState == GameState.ShipPlacement && !overlayActive)
|
||
{
|
||
ClearHighlight();
|
||
gameManager.SetInputMode(GameManager.InputMode.ShipPlacement);
|
||
return;
|
||
}
|
||
int cols = grid.ColCount(gridRow);
|
||
if (cols > 0) { gridCol = (gridCol - 1 + cols) % cols; moved = true; }
|
||
}
|
||
if (In.GetButtonDown(rightKey))
|
||
{
|
||
int cols = grid.ColCount(gridRow);
|
||
if (cols > 0) { gridCol = (gridCol + 1) % cols; moved = true; }
|
||
}
|
||
|
||
if (moved)
|
||
{
|
||
Button target = grid.GetButton(gridRow, gridCol);
|
||
if (target != null)
|
||
{
|
||
int idx = buttons.IndexOf(target);
|
||
if (idx >= 0) currentIndex = idx;
|
||
}
|
||
UpdateCursorHighlight();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// --- Старая линейная навигация (все экраны без ButtonGridLayout) ---
|
||
if (In.GetButtonDown(upKey)) { MoveNext(-1); moved = true; }
|
||
if (In.GetButtonDown(downKey)) { MoveNext(1); moved = true; }
|
||
if (In.GetButtonDown(leftKey))
|
||
{
|
||
bool overlayActive = uiManager != null && uiManager.GetActiveOverlay() != null;
|
||
if (gameManager.currentState == GameState.ShipPlacement && !overlayActive)
|
||
{
|
||
ClearHighlight();
|
||
gameManager.SetInputMode(GameManager.InputMode.ShipPlacement);
|
||
return;
|
||
}
|
||
else { MoveNext(-1); moved = true; }
|
||
}
|
||
if (In.GetButtonDown(rightKey)) { MoveNext(1); moved = true; }
|
||
|
||
if (moved) UpdateCursorHighlight();
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (In.GetButtonDown(selectKey))
|
||
{
|
||
if (buttons[currentIndex].interactable)
|
||
buttons[currentIndex].onClick.Invoke();
|
||
}
|
||
}
|
||
|
||
void MoveNext(int direction)
|
||
{
|
||
int startIndex = currentIndex;
|
||
do
|
||
{
|
||
currentIndex = (currentIndex + direction + buttons.Count) % buttons.Count;
|
||
}
|
||
while (!buttons[currentIndex].interactable && currentIndex != startIndex);
|
||
|
||
UpdateCursorHighlight();
|
||
}
|
||
|
||
void RefreshButtons()
|
||
{
|
||
buttons.Clear();
|
||
|
||
Button[] foundButtons = GetButtonsFromTopPanel();
|
||
|
||
foreach (Button btn in foundButtons)
|
||
{
|
||
if (btn.gameObject.activeInHierarchy)
|
||
buttons.Add(btn);
|
||
}
|
||
|
||
if (buttons.Count == 0)
|
||
{
|
||
currentIndex = 0;
|
||
ClearHighlight();
|
||
return;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> interactable <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
currentIndex = 0;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (!buttons[currentIndex].interactable)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> interactable <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
for (int i = 0; i < buttons.Count; i++)
|
||
{
|
||
if (buttons[i].interactable)
|
||
{
|
||
currentIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
UpdateCursorHighlight();
|
||
}
|
||
|
||
/// <summary>
|
||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||
/// </summary>
|
||
private Button[] GetButtonsFromTopPanel()
|
||
{
|
||
if (parentCanvas == null)
|
||
return new Button[0];
|
||
|
||
if (uiManager == null)
|
||
return parentCanvas.GetComponentsInChildren<Button>(false);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> overlay <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> UIManager
|
||
GameObject activeOverlay = uiManager.GetActiveOverlay();
|
||
if (activeOverlay != null)
|
||
return activeOverlay.GetComponentsInChildren<Button>(false);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD> overlay - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> screen
|
||
GameObject activeScreen = uiManager.GetActiveScreen();
|
||
if (activeScreen != null)
|
||
return activeScreen.GetComponentsInChildren<Button>(false);
|
||
|
||
// Fallback <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Canvas
|
||
return parentCanvas.GetComponentsInChildren<Button>(false);
|
||
}
|
||
|
||
void UpdateCursorHighlight()
|
||
{
|
||
for (int i = 0; i < buttons.Count; i++)
|
||
{
|
||
var btn = buttons[i];
|
||
bool isCurrent = (i == currentIndex);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1: <20><><EFBFBD><EFBFBD><EFBFBD> UIButtonHighlight (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
var highlight = btn.GetComponent<UIButtonHighlight>();
|
||
if (highlight)
|
||
{
|
||
highlight.SetHighlighted(isCurrent);
|
||
}
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2: <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Sprite Swap - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SelectableState
|
||
else if (btn.transition == Selectable.Transition.SpriteSwap)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (isCurrent)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Highlighted <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
btn.OnPointerEnter(null);
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Normal <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
btn.OnPointerExit(null);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void ClearHighlight()
|
||
{
|
||
foreach (var btn in buttons)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1: <20><><EFBFBD><EFBFBD><EFBFBD> UIButtonHighlight
|
||
var highlight = btn.GetComponent<UIButtonHighlight>();
|
||
if (highlight)
|
||
{
|
||
highlight.SetHighlighted(false);
|
||
}
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2: <20><><EFBFBD> Sprite Swap <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
else if (btn.transition == Selectable.Transition.SpriteSwap)
|
||
{
|
||
btn.OnPointerExit(null);
|
||
}
|
||
}
|
||
}
|
||
}
|