Files
2025TapTapGameJam/Assets/Script/Core/UI/UIManager.cs
2025-10-15 21:31:13 +08:00

147 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using System.Collections.Generic;
using System.Linq;
namespace Core
{
public enum UILayer
{
Background,
Normal,
Popup,
Top
}
/// <summary>
/// 单例UI管理者控制UI的层级关系UI的开关
/// </summary>
public class UIManager : MonoSingleton<UIManager>
{
public bool IsHasNonBackgroundUIActive
{
get
{ return openedUIs.Values.Any(ui => ui.gameObject.activeSelf && ui.transform.parent != layerRoots[UILayer.Background]); }
}
private Dictionary<UILayer, Transform> layerRoots = new Dictionary<UILayer, Transform>();
private Dictionary<string, UIBase> openedUIs = new Dictionary<string, UIBase>();
private IInputManager inputManager;
public void RegisterInputManager(IInputManager inputMgr)
{
inputManager = inputMgr;
}
public void RegisterLayer(UILayer layer, Transform root)
{
if (!layerRoots.ContainsKey(layer))
{
layerRoots[layer] = root;
// 注册场景中已存在的UI
// 遍历子对象
foreach (Transform child in root)
{
var uiName = child.gameObject.name;
UIBase uiBase = child.GetComponent<UIBase>();
if (uiBase != null && !openedUIs.ContainsKey(uiName))
{
openedUIs[uiName] = uiBase;
uiBase.Hide(); // 默认关闭
if (uiBase.IsOpenOnFirstLoad)
{
uiBase.Show();
}
}
}
}
}
public T OpenUI<T>(UILayer layer = UILayer.Normal) where T : Component
{
string uiName = typeof(T).Name;
if (openedUIs.ContainsKey(uiName))
{
openedUIs[uiName].Show();
UpdateCursorState();
return openedUIs[uiName] as T;
}
// 加载UI预制体
GameObject prefab = Resources.Load<GameObject>("UI/" + uiName); // 从 Resources/UI 文件夹加载UI预制体
if (prefab == null)
{
Debug.LogError("UI Prefab not found: " + uiName);
return null;
}
GameObject uiObj = Instantiate(prefab, layerRoots[layer]); // 实例化并设置父对象
UIBase uiBase = uiObj.GetComponent<UIBase>(); // 获取UIBase组件
openedUIs[uiName] = uiBase; // 注册到字典中
uiBase.Show(); // 显示UI
UpdateCursorState(); // 更新鼠标状态
return uiBase as T;
}
public void CloseUI<T>() where T : Component
{
string uiName = typeof(T).Name;
if (openedUIs.ContainsKey(uiName))
{
openedUIs[uiName].Hide();
UpdateCursorState();
}
}
// 来回切换UI状态按同一个键实现UI的开关
public void SwitchUI<T>(UILayer layer = UILayer.Normal) where T : Component
{
string uiName = typeof(T).Name;
if (openedUIs.ContainsKey(uiName) && openedUIs[uiName].gameObject.activeSelf)
{
CloseUI<T>();
}
else
{
OpenUI<T>(layer);
}
}
public Dictionary<UILayer, List<GameObject>> GetExistingUIsByLayer()
{
var result = new Dictionary<UILayer, List<GameObject>>();
foreach (var kvp in layerRoots)
{
var layer = kvp.Key;
var root = kvp.Value;
var uiList = new List<GameObject>();
foreach (Transform child in root)
{
UIBase uiBase = child.GetComponent<UIBase>();
if (uiBase != null)
uiList.Add(uiBase.gameObject);
}
result[layer] = uiList;
}
return result;
}
private void UpdateCursorState()
{
if(inputManager == null) return;
bool shouldLockCursor = !IsHasNonBackgroundUIActive; //&& !isInMainMenu; // 仅在没有非Background UI且不在主菜单时锁定鼠标
if (shouldLockCursor)
{
inputManager.SetCursorState(false, CursorLockMode.Locked);
}
else
{
inputManager.SetCursorState(true, CursorLockMode.None);
}
inputManager.SetInputForLook(shouldLockCursor);
inputManager.SetInputForMove(shouldLockCursor);
}
}
}