feat(init): 搭建初始的项目框架
This commit is contained in:
37
Assets/Script/Core/UI/UIBase.cs
Normal file
37
Assets/Script/Core/UI/UIBase.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all UI components.
|
||||
/// </summary>
|
||||
public abstract class UIBase : MonoBehaviour
|
||||
{
|
||||
public bool IsOpenOnFirstLoad;
|
||||
/// <summary>
|
||||
/// Called when the UI is shown.
|
||||
/// </summary>
|
||||
public virtual void Show()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the UI is hidden.
|
||||
/// </summary>
|
||||
public virtual void Hide()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the UI is initialized.
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
// Override in derived classes for initialization logic.
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Script/Core/UI/UIBase.cs.meta
Normal file
11
Assets/Script/Core/UI/UIBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68b45d1df56287c4ba5489104835f768
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
32
Assets/Script/Core/UI/UICamera.cs
Normal file
32
Assets/Script/Core/UI/UICamera.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class UICamera : MonoBehaviour
|
||||
{
|
||||
public static UICamera Instance { get; private set; }
|
||||
private Camera uiCamera;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
|
||||
uiCamera = GetComponent<Camera>();
|
||||
uiCamera.clearFlags = CameraClearFlags.Depth;
|
||||
uiCamera.cullingMask = LayerMask.GetMask("UI");
|
||||
uiCamera.orthographic = true;
|
||||
uiCamera.depth = 100; // 确保在主相机之后渲染
|
||||
}
|
||||
|
||||
public Camera GetCamera()
|
||||
{
|
||||
return uiCamera;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Script/Core/UI/UICamera.cs.meta
Normal file
11
Assets/Script/Core/UI/UICamera.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6653afda52a99784a9e0d5650ce2df10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/Script/Core/UI/UILayerRoot.cs
Normal file
18
Assets/Script/Core/UI/UILayerRoot.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
namespace Core
|
||||
{
|
||||
// 挂在 NormalCanvas 上的脚本
|
||||
public class UILayerRoot : MonoBehaviour
|
||||
{
|
||||
public UILayer layer;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (UIManager.Instance != null)
|
||||
{
|
||||
UIManager.Instance.RegisterLayer(layer, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
Assets/Script/Core/UI/UILayerRoot.cs.meta
Normal file
11
Assets/Script/Core/UI/UILayerRoot.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a5cdded3cae71848bcb0e7ca91e4570
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
139
Assets/Script/Core/UI/UIManager.cs
Normal file
139
Assets/Script/Core/UI/UIManager.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
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>();
|
||||
|
||||
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()
|
||||
{
|
||||
bool shouldLockCursor = !IsHasNonBackgroundUIActive; //&& !isInMainMenu; // 仅在没有非Background UI且不在主菜单时锁定鼠标
|
||||
if (shouldLockCursor)
|
||||
{
|
||||
InputManager.Instance.SetCursorState(false, CursorLockMode.Locked);
|
||||
}
|
||||
else
|
||||
{
|
||||
InputManager.Instance.SetCursorState(true, CursorLockMode.None);
|
||||
|
||||
}
|
||||
InputManager.Instance.SetInputForLook(shouldLockCursor);
|
||||
InputManager.Instance.SetInputForMove(shouldLockCursor);
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Script/Core/UI/UIManager.cs.meta
Normal file
2
Assets/Script/Core/UI/UIManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2e569d59b9a9da499d7a33a426c18f6
|
Reference in New Issue
Block a user