AlicizaX/Client/Packages/com.alicizax.unity.ui/Runtime/UI/UIComponent.cs

163 lines
5.5 KiB
C#
Raw Normal View History

2025-01-24 16:21:00 +08:00
using System;
using AlicizaX.Runtime;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace AlicizaX.UI.Runtime
{
[DisallowMultipleComponent]
[AddComponentMenu("Game Framework/UI")]
[UnityEngine.Scripting.Preserve]
public sealed partial class UIComponent : GameFrameworkComponent
{
[SerializeField] private GameObject uiRoot = null;
private Transform m_InstanceRoot = null;
private IUIManager _uiManager;
public const int WINDOW_HIDE_LAYER = 2; // Ignore Raycast
public const int WINDOW_SHOW_LAYER = 5; // UI
public Camera UICamera => _uiManager?.UICamera;
public Transform UIRoot => _uiManager.UICanvasRoot;
protected override void Awake()
{
ImplementationComponentType = Utility.Assembly.GetType(componentType);
InterfaceComponentType = typeof(IUIManager);
base.Awake();
_uiManager = SysModuleCenter.GetModule<IUIManager>();
if (uiRoot == null)
{
uiRoot = Resources.Load<GameObject>("UIRoot");
GameObject obj = GameObject.Instantiate(uiRoot, Vector3.zero, Quaternion.identity);
2025-01-24 17:41:31 +08:00
obj.name = "------UI Root------";
2025-01-24 16:21:00 +08:00
m_InstanceRoot = obj.transform;
Object.DontDestroyOnLoad(m_InstanceRoot);
_uiManager.Initlize(m_InstanceRoot);
}
}
#region
/// <summary>
/// 设置屏幕安全区域(异形屏支持)。
/// </summary>
/// <param name="safeRect">安全区域</param>
public void ApplyScreenSafeRect(Rect safeRect)
{
CanvasScaler scaler = _uiManager.UICanvasRoot.GetComponent<CanvasScaler>();
if (scaler == null)
{
Log.Error($"Not found {nameof(CanvasScaler)} !");
return;
}
// Convert safe area rectangle from absolute pixels to UGUI coordinates
float rateX = scaler.referenceResolution.x / Screen.width;
float rateY = scaler.referenceResolution.y / Screen.height;
float posX = (int)(safeRect.position.x * rateX);
float posY = (int)(safeRect.position.y * rateY);
float width = (int)(safeRect.size.x * rateX);
float height = (int)(safeRect.size.y * rateY);
float offsetMaxX = scaler.referenceResolution.x - width - posX;
float offsetMaxY = scaler.referenceResolution.y - height - posY;
// 注意:安全区坐标系的原点为左下角
var rectTrans = _uiManager.UICanvasRoot.transform as RectTransform;
if (rectTrans != null)
{
rectTrans.offsetMin = new Vector2(posX, posY); //锚框状态下的屏幕左下角偏移向量
rectTrans.offsetMax = new Vector2(-offsetMaxX, -offsetMaxY); //锚框状态下的屏幕右上角偏移向量
}
}
/// <summary>
/// 模拟IPhoneX异形屏
/// </summary>
public void SimulateIPhoneXNotchScreen()
{
Rect rect;
if (Screen.height > Screen.width)
{
// 竖屏Portrait
float deviceWidth = 1125;
float deviceHeight = 2436;
rect = new Rect(0f / deviceWidth, 102f / deviceHeight, 1125f / deviceWidth, 2202f / deviceHeight);
}
else
{
// 横屏Landscape
float deviceWidth = 2436;
float deviceHeight = 1125;
rect = new Rect(132f / deviceWidth, 63f / deviceHeight, 2172f / deviceWidth, 1062f / deviceHeight);
}
Rect safeArea = new Rect(Screen.width * rect.x, Screen.height * rect.y, Screen.width * rect.width, Screen.height * rect.height);
ApplyScreenSafeRect(safeArea);
}
#endregion
public T ShowUI<T>(params System.Object[] userDatas) where T : UIWindow
{
return (T)ShowUI(typeof(T), userDatas);
}
public UIWindow ShowUI(Type type, params System.Object[] userDatas)
{
return _uiManager.ShowUI(type, userDatas);
}
public async UniTask<T> ShowUIAsync<T>(params System.Object[] userDatas) where T : UIWindow
{
return (T)await ShowUIAsync(typeof(T), userDatas);
}
public async UniTask<UIWindow> ShowUIAsync(Type type, params System.Object[] userDatas)
{
return await _uiManager.ShowUIAsync(type, userDatas);
}
public UIWindow ShowUI(string windowName, params System.Object[] userDatas)
{
Type uiType = UITypeCollector.GetUIInst(windowName);
return ShowUI(uiType, userDatas);
}
public async UniTask<UIWindow> ShowUIAsync(string windowName, params System.Object[] userDatas)
{
Type uiType = UITypeCollector.GetUIInst(windowName);
return await ShowUIAsync(uiType, userDatas);
}
public void CloseUI<T>(bool force = false) where T : UIWindow
{
CloseUI(typeof(T), force);
}
public void CloseUI(Type type, bool force = false)
{
_uiManager.CloseUI(type, force);
}
public T GetUI<T>() where T : UIWindow
{
return (T)GetUI(typeof(T));
}
public UIWindow GetUI(Type type)
{
return _uiManager.GetUI(type);
}
}
}