using System; using AlicizaX.Resource.Runtime; using AlicizaX.Runtime; using AlicizaX.Timer.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 UIHideLayer = 2; // Ignore Raycast public const int UIShowLayer = 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(); if (uiRoot == null) { throw new GameFrameworkException("UIRoot Prefab is invalid."); } GameObject obj = Instantiate(uiRoot, Vector3.zero, Quaternion.identity); obj.name = "------UI Root------"; m_InstanceRoot = obj.transform; Object.DontDestroyOnLoad(m_InstanceRoot); _uiManager.Initlize(m_InstanceRoot); } private void Start() { _uiManager.SetTimerManager(SysModuleCenter.GetModule()); } #region 设置安全区域 /// /// 设置屏幕安全区域(异形屏支持)。 /// /// 安全区域 public void ApplyScreenSafeRect(Rect safeRect) { CanvasScaler scaler = _uiManager.UICanvasRoot.GetComponent(); 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); //锚框状态下的屏幕右上角偏移向量 } } /// /// 模拟IPhoneX异形屏 /// 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(params System.Object[] userDatas) where T : UIWindow { return (T)ShowUI(typeof(T), userDatas); } public async UniTask ShowUIAsync(params System.Object[] userDatas) where T : UIWindow { return (T)await ShowUIAsync(typeof(T), userDatas); } public UIBase ShowUI(string windowName, params System.Object[] userDatas) { Type uiType = UITypeCollector.GetUIInst(windowName); GameFrameworkGuard.NotNull(uiType, nameof(uiType)); return ShowUI(uiType, userDatas); } public async UniTask ShowUIAsync(string windowName, params System.Object[] userDatas) { Type uiType = UITypeCollector.GetUIInst(windowName); GameFrameworkGuard.NotNull(uiType, nameof(uiType)); return await ShowUIAsync(uiType, userDatas); } public void CloseUI(bool force = false) where T : UIWindow { CloseUI(typeof(T), force); } public T GetUI() where T : UIWindow { return (T)GetUI(typeof(T)); } public UIBase ShowUI(Type type, params System.Object[] userDatas) { return _uiManager.ShowUI(type, userDatas); } public async UniTask ShowUIAsync(Type type, params System.Object[] userDatas) { return await _uiManager.ShowUIAsync(type, userDatas); } private void CloseUI(Type type, bool force = false) { _uiManager.CloseUI(type, force); } private UIBase GetUI(Type type) { return _uiManager.GetUI(type); } } }