420 lines
15 KiB
C#
420 lines
15 KiB
C#
using System;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace XGame
|
|
{
|
|
// 匹配大厅运行时控制器。沿用 AuthRegisterLoginController 模式:
|
|
// 按节点名缓存控件、克隆模板行、回调 Lua。只传基本类型跨 XLua。
|
|
public class GameLobbyController : MonoBehaviour
|
|
{
|
|
private Transform listGames;
|
|
private GameObject itemTemplate;
|
|
private TMP_Text statusText;
|
|
private RectTransform panelLobby;
|
|
private RectTransform collapseButtonRect;
|
|
private Button collapseButton;
|
|
private TMP_Text collapseText;
|
|
private GameObject titleObject;
|
|
private GameObject scrollObject;
|
|
private Vector2 expandedPanelSize;
|
|
private Vector2 expandedButtonPosition;
|
|
private bool hasCollapseMetrics;
|
|
private bool leftLayoutApplied;
|
|
private bool rootMatchButtonBound;
|
|
private bool collapsed;
|
|
private string currentStatus = string.Empty;
|
|
private string luaModule = "client/baseworld";
|
|
public Action<string> OnMatch;
|
|
private const float LobbyPanelWidth = 520f;
|
|
private const float LobbyPanelHeight = 296f;
|
|
private const float LobbyPanelLeft = 24f;
|
|
private const float LobbyPanelTop = -24f;
|
|
private const float CollapsedPanelWidth = 56f;
|
|
|
|
private void Awake()
|
|
{
|
|
CacheControls();
|
|
}
|
|
|
|
public void Bind(string module)
|
|
{
|
|
if (!string.IsNullOrEmpty(module))
|
|
{
|
|
luaModule = module;
|
|
}
|
|
}
|
|
|
|
// 清空旧克隆行
|
|
public void BeginGames()
|
|
{
|
|
CacheControls();
|
|
if (listGames == null)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = listGames.childCount - 1; i >= 0; i--)
|
|
{
|
|
Transform child = listGames.GetChild(i);
|
|
if (itemTemplate != null && child == itemTemplate.transform)
|
|
{
|
|
continue;
|
|
}
|
|
Destroy(child.gameObject);
|
|
}
|
|
}
|
|
|
|
// 逐行追加。gameId 按行捕获用于点击回调
|
|
public void AddGame(string gameId, string name, string players)
|
|
{
|
|
CacheControls();
|
|
if (itemTemplate == null || listGames == null)
|
|
{
|
|
return;
|
|
}
|
|
GameObject row = Instantiate(itemTemplate, listGames);
|
|
row.name = "Item_Game_" + gameId;
|
|
row.SetActive(true);
|
|
SetChildText(row.transform, "Txt_GameName", name);
|
|
SetChildText(row.transform, "Txt_Players", players);
|
|
|
|
Transform btnTf = row.transform.FindTransform("Btn_Match");
|
|
if (btnTf != null)
|
|
{
|
|
Button btn = btnTf.GetComponent<Button>();
|
|
if (btn != null)
|
|
{
|
|
string captured = gameId;
|
|
btn.onClick.RemoveAllListeners();
|
|
btn.onClick.AddListener(() => OnMatch?.Invoke(captured));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void EndGames()
|
|
{
|
|
}
|
|
|
|
public void SetStatus(string message)
|
|
{
|
|
CacheControls();
|
|
currentStatus = message ?? string.Empty;
|
|
if (statusText == null)
|
|
{
|
|
return;
|
|
}
|
|
statusText.text = currentStatus;
|
|
statusText.gameObject.SetActive(!collapsed && !string.IsNullOrEmpty(currentStatus));
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
private void CacheControls()
|
|
{
|
|
if (panelLobby == null)
|
|
{
|
|
Transform t = transform.FindTransform("Panel_Lobby");
|
|
panelLobby = t == null ? null : t.GetComponent<RectTransform>();
|
|
}
|
|
EnsureCollapseButton();
|
|
if (collapseButton == null)
|
|
{
|
|
Transform t = transform.FindTransform("Btn_Collapse");
|
|
if (t != null)
|
|
{
|
|
collapseButtonRect = t.GetComponent<RectTransform>();
|
|
collapseButton = t.GetComponent<Button>();
|
|
if (collapseButton != null)
|
|
{
|
|
collapseButton.onClick.RemoveAllListeners();
|
|
collapseButton.onClick.AddListener(ToggleCollapsed);
|
|
}
|
|
}
|
|
}
|
|
if (collapseText == null)
|
|
{
|
|
Transform t = transform.FindTransform("Txt_Collapse");
|
|
collapseText = t == null ? null : t.GetComponent<TMP_Text>();
|
|
}
|
|
if (titleObject == null)
|
|
{
|
|
Transform t = transform.FindTransform("Txt_Title");
|
|
titleObject = t == null ? null : t.gameObject;
|
|
}
|
|
if (scrollObject == null)
|
|
{
|
|
Transform t = transform.FindTransform("Scroll_Games");
|
|
scrollObject = t == null ? null : t.gameObject;
|
|
}
|
|
if (listGames == null)
|
|
{
|
|
listGames = transform.FindTransform("List_Games");
|
|
}
|
|
if (itemTemplate == null)
|
|
{
|
|
Transform t = transform.FindTransform("Item_Game");
|
|
itemTemplate = t == null ? null : t.gameObject;
|
|
}
|
|
if (statusText == null)
|
|
{
|
|
Transform t = transform.FindTransform("Txt_Status");
|
|
statusText = t == null ? null : t.GetComponent<TMP_Text>();
|
|
}
|
|
BindRootMatchButton();
|
|
ApplyLeftDockLayout();
|
|
if (!hasCollapseMetrics && panelLobby != null && collapseButtonRect != null)
|
|
{
|
|
expandedPanelSize = panelLobby.sizeDelta;
|
|
expandedButtonPosition = collapseButtonRect.anchoredPosition;
|
|
hasCollapseMetrics = true;
|
|
ApplyCollapsedState();
|
|
}
|
|
}
|
|
|
|
private void BindRootMatchButton()
|
|
{
|
|
if (rootMatchButtonBound)
|
|
{
|
|
return;
|
|
}
|
|
Transform matchButton = transform.FindTransform("Btn_Match");
|
|
if (matchButton == null || itemTemplate != null && matchButton.IsChildOf(itemTemplate.transform))
|
|
{
|
|
return;
|
|
}
|
|
Button btn = matchButton.GetComponent<Button>();
|
|
if (btn == null)
|
|
{
|
|
return;
|
|
}
|
|
rootMatchButtonBound = true;
|
|
btn.onClick.RemoveAllListeners();
|
|
btn.onClick.AddListener(() => OnMatch?.Invoke(string.Empty));
|
|
}
|
|
|
|
private void EnsureCollapseButton()
|
|
{
|
|
if (transform.FindTransform("Btn_Collapse") != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Transform parent = panelLobby != null && panelLobby.parent != null ? panelLobby.parent : transform;
|
|
GameObject buttonGo = new GameObject("Btn_Collapse", typeof(RectTransform), typeof(Image), typeof(Button));
|
|
buttonGo.transform.SetParent(parent, false);
|
|
|
|
RectTransform rt = buttonGo.GetComponent<RectTransform>();
|
|
rt.anchorMin = new Vector2(0f, 1f);
|
|
rt.anchorMax = new Vector2(0f, 1f);
|
|
rt.pivot = new Vector2(0f, 1f);
|
|
rt.anchoredPosition = new Vector2(LobbyPanelLeft + LobbyPanelWidth, LobbyPanelTop);
|
|
rt.sizeDelta = new Vector2(48f, 72f);
|
|
|
|
Image img = buttonGo.GetComponent<Image>();
|
|
Image matchImage = null;
|
|
Transform matchButton = transform.FindTransform("Btn_Match");
|
|
if (matchButton != null)
|
|
{
|
|
matchImage = matchButton.GetComponent<Image>();
|
|
}
|
|
img.sprite = matchImage != null ? matchImage.sprite : null;
|
|
img.type = matchImage != null ? matchImage.type : Image.Type.Sliced;
|
|
img.color = new Color(0.239f, 0.482f, 1f, 1f);
|
|
img.raycastTarget = true;
|
|
|
|
GameObject textGo = new GameObject("Txt_Collapse", typeof(RectTransform), typeof(TextMeshProUGUI));
|
|
textGo.transform.SetParent(buttonGo.transform, false);
|
|
RectTransform textRt = textGo.GetComponent<RectTransform>();
|
|
textRt.anchorMin = Vector2.zero;
|
|
textRt.anchorMax = Vector2.one;
|
|
textRt.pivot = new Vector2(0.5f, 0.5f);
|
|
textRt.offsetMin = Vector2.zero;
|
|
textRt.offsetMax = Vector2.zero;
|
|
|
|
TextMeshProUGUI text = textGo.GetComponent<TextMeshProUGUI>();
|
|
text.text = "<";
|
|
text.fontSize = 34f;
|
|
text.fontStyle = FontStyles.Bold;
|
|
text.alignment = TextAlignmentOptions.Center;
|
|
text.color = Color.white;
|
|
text.raycastTarget = false;
|
|
}
|
|
|
|
private void ApplyLeftDockLayout()
|
|
{
|
|
if (leftLayoutApplied)
|
|
{
|
|
return;
|
|
}
|
|
leftLayoutApplied = true;
|
|
|
|
if (panelLobby != null)
|
|
{
|
|
panelLobby.anchorMin = new Vector2(0f, 1f);
|
|
panelLobby.anchorMax = new Vector2(0f, 1f);
|
|
panelLobby.pivot = new Vector2(0f, 1f);
|
|
panelLobby.anchoredPosition = new Vector2(LobbyPanelLeft, LobbyPanelTop);
|
|
panelLobby.sizeDelta = new Vector2(LobbyPanelWidth, LobbyPanelHeight);
|
|
}
|
|
if (collapseButtonRect != null)
|
|
{
|
|
collapseButtonRect.anchorMin = new Vector2(0f, 1f);
|
|
collapseButtonRect.anchorMax = new Vector2(0f, 1f);
|
|
collapseButtonRect.pivot = new Vector2(0f, 1f);
|
|
collapseButtonRect.anchoredPosition = new Vector2(LobbyPanelLeft + LobbyPanelWidth, LobbyPanelTop);
|
|
collapseButtonRect.sizeDelta = new Vector2(48f, 72f);
|
|
}
|
|
|
|
SetRect("Txt_Title", new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -14f), new Vector2(448f, 36f));
|
|
SetOffsets("Scroll_Games", new Vector2(16f, 52f), new Vector2(-16f, -58f));
|
|
SetRect("Txt_Status", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 16f), new Vector2(448f, 28f));
|
|
SetRect("Item_Game", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), Vector2.zero, new Vector2(0f, 76f));
|
|
SetLayoutElement("Item_Game", 76f);
|
|
SetRect("Txt_GameName", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(18f, 12f), new Vector2(280f, 28f));
|
|
SetRect("Txt_Players", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(18f, -14f), new Vector2(280f, 22f));
|
|
SetRect("Btn_Match", new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-10f, 0f), new Vector2(104f, 46f));
|
|
|
|
Transform titleText = transform.FindTransform("Txt_Title");
|
|
if (titleText != null)
|
|
{
|
|
TMP_Text text = titleText.GetComponent<TMP_Text>();
|
|
if (text != null)
|
|
{
|
|
text.fontSize = 28f;
|
|
}
|
|
}
|
|
Transform gameNameText = transform.FindTransform("Txt_GameName");
|
|
if (gameNameText != null)
|
|
{
|
|
TMP_Text text = gameNameText.GetComponent<TMP_Text>();
|
|
if (text != null)
|
|
{
|
|
text.fontSize = 22f;
|
|
}
|
|
}
|
|
Transform matchText = transform.FindTransform("Txt_Match");
|
|
if (matchText != null)
|
|
{
|
|
TMP_Text text = matchText.GetComponent<TMP_Text>();
|
|
if (text != null)
|
|
{
|
|
text.fontSize = 24f;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ToggleCollapsed()
|
|
{
|
|
collapsed = !collapsed;
|
|
ApplyCollapsedState();
|
|
}
|
|
|
|
private void ApplyCollapsedState()
|
|
{
|
|
if (!hasCollapseMetrics)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panelLobby != null)
|
|
{
|
|
panelLobby.sizeDelta = collapsed ? new Vector2(CollapsedPanelWidth, expandedPanelSize.y) : expandedPanelSize;
|
|
}
|
|
if (collapseButtonRect != null)
|
|
{
|
|
collapseButtonRect.anchoredPosition = collapsed
|
|
? new Vector2(panelLobby != null ? panelLobby.anchoredPosition.x + CollapsedPanelWidth : LobbyPanelLeft + CollapsedPanelWidth, expandedButtonPosition.y)
|
|
: expandedButtonPosition;
|
|
}
|
|
if (collapseText != null)
|
|
{
|
|
collapseText.text = collapsed ? ">" : "<";
|
|
}
|
|
if (titleObject != null)
|
|
{
|
|
titleObject.SetActive(!collapsed);
|
|
}
|
|
if (scrollObject != null)
|
|
{
|
|
scrollObject.SetActive(!collapsed);
|
|
}
|
|
if (statusText != null)
|
|
{
|
|
statusText.gameObject.SetActive(!collapsed && !string.IsNullOrEmpty(currentStatus));
|
|
}
|
|
}
|
|
|
|
private void SetRect(string nodeName, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPosition, Vector2 sizeDelta)
|
|
{
|
|
Transform t = transform.FindTransform(nodeName);
|
|
if (t == null)
|
|
{
|
|
return;
|
|
}
|
|
RectTransform rt = t.GetComponent<RectTransform>();
|
|
if (rt == null)
|
|
{
|
|
return;
|
|
}
|
|
rt.anchorMin = anchorMin;
|
|
rt.anchorMax = anchorMax;
|
|
rt.pivot = pivot;
|
|
rt.anchoredPosition = anchoredPosition;
|
|
rt.sizeDelta = sizeDelta;
|
|
}
|
|
|
|
private void SetOffsets(string nodeName, Vector2 offsetMin, Vector2 offsetMax)
|
|
{
|
|
Transform t = transform.FindTransform(nodeName);
|
|
if (t == null)
|
|
{
|
|
return;
|
|
}
|
|
RectTransform rt = t.GetComponent<RectTransform>();
|
|
if (rt == null)
|
|
{
|
|
return;
|
|
}
|
|
rt.anchorMin = Vector2.zero;
|
|
rt.anchorMax = Vector2.one;
|
|
rt.pivot = new Vector2(0.5f, 0.5f);
|
|
rt.offsetMin = offsetMin;
|
|
rt.offsetMax = offsetMax;
|
|
}
|
|
|
|
private void SetLayoutElement(string nodeName, float height)
|
|
{
|
|
Transform t = transform.FindTransform(nodeName);
|
|
if (t == null)
|
|
{
|
|
return;
|
|
}
|
|
LayoutElement layout = t.GetComponent<LayoutElement>();
|
|
if (layout == null)
|
|
{
|
|
return;
|
|
}
|
|
layout.minHeight = height;
|
|
layout.preferredHeight = height;
|
|
}
|
|
|
|
private static void SetChildText(Transform root, string childName, string text)
|
|
{
|
|
Transform t = root.FindTransform(childName);
|
|
if (t != null)
|
|
{
|
|
TMP_Text label = t.GetComponent<TMP_Text>();
|
|
if (label != null)
|
|
{
|
|
label.text = text ?? string.Empty;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|