Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user