sea-battle/Assets/Scripts/PlayerCursorUI.cs

311 lines
8.7 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class PlayerCursorUI : MonoBehaviour
{
public GameManager gameManager;
public Canvas parentCanvas; // Êàíâàñ ýòîãî èãðîêà
public int playerId = 1; // 1 èëè 2 (äëÿ óïðàâëåíèÿ)
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;
// Ôëàã ÷òî ïàíåëü èçìåíèëàñü è íóæíî îáíîâèòü êíîïêè
private bool panelChanged = false;
void Start()
{
var player = GetComponentInParent<Player>();
if (player != null)
playerId = player.PlayerId;
EnsureUIManager();
DetectInputDevice();
BindControls();
RefreshButtons();
}
void Awake()
{
EnsureUIManager();
}
void DetectInputDevice()
{
// Ïðîâåðÿåì, åñòü ëè ïîäêëþ÷¸ííûå äæîéñòèêè
var joysticks = Input.GetJoystickNames();
if (joysticks.Length > 0 && !string.IsNullOrEmpty(joysticks[0]))
useJoystick = true;
else
useJoystick = false;
}
void BindControls()
{
if (!useJoystick) // êëàâèàòóðà
{
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;
// Åñëè ïàíåëü èçìåíèëàñü - ïðèíóäèòåëüíî îáíîâëÿåì êíîïêè
if (panelChanged)
{
RefreshButtons();
panelChanged = false;
return; // Ïðîïóñêàåì ýòîò êàäð ÷òîáû äàòü âðåìÿ îáíîâèòüñÿ
}
// Åñëè àêòèâíàÿ ïàíåëü ñìåíèëàñü èëè êíîïêà èñ÷åçëà — îáíîâëÿåì
if (buttons.Count == 0 || !buttons[currentIndex].gameObject.activeInHierarchy)
{
RefreshButtons();
}
if (buttons.Count == 0) return;
bool moved = false;
// Äâèæåíèå ïî êíîïêàì
if (In.GetButtonDown(upKey)) { MoveNext(-1); moved = true; }
if (In.GetButtonDown(downKey)) { MoveNext(1); moved = true; }
if (In.GetButtonDown(leftKey))
{
//  ShipPlacement ïåðåêëþ÷àåì InputMode òîëüêî åñëè ÍÅÒ àêòèâíîãî overlay
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();
// Âûáîð êíîïêè
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;
}
// Óñòàíàâëèâàåì íà ïåðâóþ interactable êíîïêó
currentIndex = 0;
// Åñëè ïåðâàÿ êíîïêà íåàêòèâíà - íàéä¸ì àêòèâíóþ
if (!buttons[currentIndex].interactable)
{
// Èùåì ïåðâóþ interactable êíîïêó
for (int i = 0; i < buttons.Count; i++)
{
if (buttons[i].interactable)
{
currentIndex = i;
break;
}
}
}
UpdateCursorHighlight();
}
/// <summary>
/// Âîçâðàùàåò êíîïêè òîëüêî ñ âåðõíåé àêòèâíîé ïàíåëè (îâåðëåé èìååò ïðèîðèòåò íàä ýêðàíîì)
/// </summary>
private Button[] GetButtonsFromTopPanel()
{
if (parentCanvas == null)
return new Button[0];
if (uiManager == null)
return parentCanvas.GetComponentsInChildren<Button>(false);
// Èùåì àêòèâíûé overlay íàïðÿìóþ ÷åðåç ìåòîä UIManager
GameObject activeOverlay = uiManager.GetActiveOverlay();
if (activeOverlay != null)
return activeOverlay.GetComponentsInChildren<Button>(false);
// Åñëè íåò overlay - èùåì àêòèâíûé screen
GameObject activeScreen = uiManager.GetActiveScreen();
if (activeScreen != null)
return activeScreen.GetComponentsInChildren<Button>(false);
// Fallback íà âñå êíîïêè èç Canvas
return parentCanvas.GetComponentsInChildren<Button>(false);
}
void UpdateCursorHighlight()
{
for (int i = 0; i < buttons.Count; i++)
{
var btn = buttons[i];
bool isCurrent = (i == currentIndex);
// Ñïîñîá 1: ×åðåç UIButtonHighlight (åñëè åñòü)
var highlight = btn.GetComponent<UIButtonHighlight>();
if (highlight)
{
highlight.SetHighlighted(isCurrent);
}
// Ñïîñîá 2: Äëÿ êíîïîê ñ Sprite Swap - èñïîëüçóåì SelectableState
else if (btn.transition == Selectable.Transition.SpriteSwap)
{
// Ïðèíóäèòåëüíî óñòàíàâëèâàåì âèçóàëüíîå ñîñòîÿíèå
if (isCurrent)
{
// Ñèìóëèðóåì Highlighted ñîñòîÿíèå
btn.OnPointerEnter(null);
}
else
{
// Âîçâðàùàåì â Normal ñîñòîÿíèå
btn.OnPointerExit(null);
}
}
}
}
void ClearHighlight()
{
foreach (var btn in buttons)
{
// Ñïîñîá 1: ×åðåç UIButtonHighlight
var highlight = btn.GetComponent<UIButtonHighlight>();
if (highlight)
{
highlight.SetHighlighted(false);
}
// Ñïîñîá 2: Äëÿ Sprite Swap êíîïîê
else if (btn.transition == Selectable.Transition.SpriteSwap)
{
btn.OnPointerExit(null);
}
}
}
}