TH1/Unity/Assets/Scripts/TH1_UI/View/Bottom/UIBottomNetView.cs
2026-05-27 22:46:45 +08:00

293 lines
7.5 KiB
C#

using System;
using System.Collections.Generic;
using Logic.Audio;
using Logic.Multilingual;
using TH1_Logic.Net;
using TH1_Logic.Steam;
using TH1Renderer;
using TH1_UI.View.Common;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using RuntimeData;
using TH1_Logic.Core;
using UnityEngine.Serialization;
namespace TH1_UI.View.Bottom
{
public class UIBottomNetView : Base.View
{
public ViDelegateAssisstant.Dele OnBtnCloseClick;
public ViDelegateAssisstant.Dele<string> OnChatMessageSend;
public GameObject NetRowPrefab;
public RectTransform NetRowContainer;
// NetInfo related
public RectTransform NetInfo;
public RectTransform ScrollViewRect;
// ChatArea
public RectTransform ChatAreaRoot;
public RectTransform NetErrorPanelRoot;
private UIChatAreaMono _chatArea;
private GameObject _chatAreaGo;
private UINetErrorAreaMono _netErrorArea;
private GameObject _netErrorAreaGo;
private List<UIBottomNetRowMono> _netInfoRowList = null;
private bool _initialized = false;
private int _lastNetMemberCount = -1;
protected override void OnInit()
{
base.OnInit();
_netInfoRowList = new List<UIBottomNetRowMono>();
}
public void SetContent()
{
Init();
UpdateView();
}
// Initializes the room member state when entering a match.
private void Init()
{
_initialized = true;
if(Main.MapData == null) return;
bool isMulti = Main.MapData.Net.Mode == NetMode.Multi;
if (NetInfo != null)
NetInfo.gameObject.SetActive(isMulti);
// ChatArea and NetErrorArea follow NetInfo lifetime.
if (isMulti)
{
InitChatArea();
InitNetErrorArea();
}
else
{
CloseChatArea();
CloseNetErrorArea();
}
if (!isMulti) return;
var lobbyInfo = LobbyManager.Instance.Lobby as SteamLobbyManager;
if (lobbyInfo == null) return;
var mids = lobbyInfo.GetAllMemberInfo();
while (_netInfoRowList.Count < mids.Count)
{
var obj = Instantiate(NetRowPrefab, NetRowContainer);
var cpn = obj.GetComponent<UIBottomNetRowMono>();
if (cpn == null) break;
_netInfoRowList.Add(cpn);
}
int i = 0;
foreach(var pair in mids)
{
_netInfoRowList[i].gameObject.SetActive(true);
_netInfoRowList[i].InitContent(pair.Key, pair.Value, pair.Key == lobbyInfo.GetLobbyOwnerId(), true);
i++;
}
int activeCount = i;
while(i < _netInfoRowList.Count)
{
_netInfoRowList[i].gameObject.SetActive(false);
i++;
}
ResizeScrollView(activeCount);
}
private void ResizeScrollView(int activeRowCount)
{
if (ScrollViewRect == null || activeRowCount <= 0) return;
float rowHeight = ((RectTransform)NetRowPrefab.transform).sizeDelta.y;
var layout = NetRowContainer.GetComponent<VerticalLayoutGroup>();
float spacing = layout != null ? layout.spacing : 0f;
float totalHeight = activeRowCount * rowHeight + Mathf.Max(0, activeRowCount - 1) * spacing;
if (layout != null)
totalHeight += layout.padding.top + layout.padding.bottom;
var sd = ScrollViewRect.sizeDelta;
sd.y = totalHeight;
ScrollViewRect.sizeDelta = sd;
}
// UpdateView only changes NetStatus and room owner marker.
public void UpdateView()
{
if (!_initialized) return;
if(Main.MapData == null) return;
bool isMulti = Main.MapData.Net.Mode == NetMode.Multi;
if (NetInfo != null)
NetInfo.gameObject.SetActive(isMulti);
if (!isMulti) return;
var lobbyInfo = LobbyManager.Instance.Lobby as SteamLobbyManager;
if (lobbyInfo == null) return;
var mids = lobbyInfo.GetAllMemberInfo();
PlayMemberEnterAudioIfNeeded(mids.Count);
// Reinitialize if the lobby member count grows.
if (mids.Count > _netInfoRowList.Count)
Init();
for (int i = 0; i < _netInfoRowList.Count; i++)
{
if (!_netInfoRowList[i].gameObject.activeSelf) break;
bool isOnline = false;
bool isRoomOwner = false;
foreach(var pair in mids)
if (pair.Key == _netInfoRowList[i].MemberId)
{
isOnline = true;
isRoomOwner = pair.Key == lobbyInfo.GetLobbyOwnerId();
break;
}
_netInfoRowList[i].UpdateNetStatus(isRoomOwner, isOnline);
}
}
private void PlayMemberEnterAudioIfNeeded(int memberCount)
{
if (_lastNetMemberCount >= 0 && memberCount > _lastNetMemberCount)
AudioManager.Instance.PlayAudio("SFX/UI_playerenter");
_lastNetMemberCount = memberCount;
}
private void Update()
{
UpdateView();
}
private void OnChatMessageSendInternal(string message)
{
OnChatMessageSend?.Invoke(message);
}
private void InitChatArea()
{
if (_chatArea != null) return;
var prefab = Resources.Load<GameObject>("Prefab/UI/Common/Chat/ChatAreaPanel");
if (prefab == null)
{
Debug.LogError("[UIBottomNet] ChatAreaPanel prefab not found.");
return;
}
var parent = ChatAreaRoot != null ? ChatAreaRoot : transform as RectTransform;
_chatAreaGo = Instantiate(prefab, parent);
FitToRoot(_chatAreaGo.transform as RectTransform, parent);
_chatArea = _chatAreaGo.GetComponent<UIChatAreaMono>();
if (_chatArea == null)
{
Debug.LogError("[UIBottomNet] ChatAreaPanel missing UIChatAreaMono.");
Destroy(_chatAreaGo);
_chatAreaGo = null;
return;
}
_chatArea.OnSendMessage -= OnChatMessageSendInternal;
_chatArea.OnSendMessage += OnChatMessageSendInternal;
_chatArea.Init();
}
private void FitToRoot(RectTransform rectTransform, RectTransform root)
{
if (rectTransform == null || root == null) return;
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
rectTransform.offsetMin = Vector2.zero;
rectTransform.offsetMax = Vector2.zero;
rectTransform.localScale = Vector3.one;
}
private void CloseChatArea()
{
if (_chatArea != null)
{
_chatArea.OnSendMessage -= OnChatMessageSendInternal;
_chatArea.Shutdown();
}
if (_chatAreaGo != null)
Destroy(_chatAreaGo);
_chatArea = null;
_chatAreaGo = null;
}
private void InitNetErrorArea()
{
if (_netErrorArea != null) return;
var prefab = Resources.Load<GameObject>("Prefab/UI/Common/Chat/NetErrorAreaPanel");
if (prefab == null)
{
Debug.LogError("[UIBottomNet] NetErrorAreaPanel prefab not found.");
return;
}
var parent = GetNetErrorPanelRoot();
_netErrorAreaGo = Instantiate(prefab, parent);
FitToRoot(_netErrorAreaGo.transform as RectTransform, parent);
_netErrorAreaGo.transform.SetAsLastSibling();
_netErrorArea = _netErrorAreaGo.GetComponent<UINetErrorAreaMono>();
if (_netErrorArea == null)
{
Debug.LogError("[UIBottomNet] NetErrorAreaPanel missing UINetErrorAreaMono.");
Destroy(_netErrorAreaGo);
_netErrorAreaGo = null;
return;
}
_netErrorArea.Init();
}
private RectTransform GetNetErrorPanelRoot()
{
if (NetErrorPanelRoot != null) return NetErrorPanelRoot;
var root = transform.Find("NetErrorPanelRoot") as RectTransform;
if (root != null)
{
NetErrorPanelRoot = root;
return NetErrorPanelRoot;
}
return ChatAreaRoot != null ? ChatAreaRoot : transform as RectTransform;
}
private void CloseNetErrorArea()
{
if (_netErrorArea != null)
_netErrorArea.Shutdown();
if (_netErrorAreaGo != null)
Destroy(_netErrorAreaGo);
_netErrorArea = null;
_netErrorAreaGo = null;
}
public void CloseView()
{
_initialized = false;
_lastNetMemberCount = -1;
// 娓呯悊 ChatArea
CloseChatArea();
CloseNetErrorArea();
//AudioManager.Instance.StopMusic();
}
}
}