| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 | using System;using System.Collections.Generic;using System.Threading.Tasks;using UnityEngine;namespace TapSDK.UI{    public class UIManager : MonoSingleton<UIManager>    {        public const int TOPPEST_SORTING_ORDER = 32767;        private const int LOADING_PANEL_SORTING_ORDER = TOPPEST_SORTING_ORDER;        private const int TOAST_PANEL_SORTING_ORDER = TOPPEST_SORTING_ORDER - 10;                private readonly Dictionary<Type, BasePanelController> _registerPanels = new Dictionary<Type, BasePanelController>();        // uicamera        private Camera _uiCamera;        private GameObject _uiRoot;        public int uiOpenOrder;// UI打开时的Order值 用来标识界面层级顺序        public Camera UiCamera => _uiCamera;        protected override void Init()        {            if (_uiRoot == null)            {                CreateUIRoot();            }        }        private void CreateUIRoot()        {            _uiRoot = Instantiate(Resources.Load<GameObject>("TapSDKUIRoot"));            DontDestroyOnLoad(_uiRoot);            var canvas = _uiRoot.GetComponent<Canvas>();            _uiCamera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? Camera.main : canvas.worldCamera;        }                /// <summary>        /// Get Or Create UI asynchronously        /// </summary>        /// <param name="path">the prefab path</param>        /// <param name="param">opening param</param>        /// <param name="onAsyncGet">if u want to get ui do something,here is for u, which is invoked after BasePanelController.OnLoadSuccess</param>        /// <typeparam name="TPanelController"></typeparam>        /// <returns>get panel instance if sync mode load</returns>        public async Task<TPanelController> OpenUIAsync<TPanelController>(string path, IOpenPanelParameter param = null, Action<BasePanelController> onAsyncGet = null) where TPanelController : BasePanelController        {            var basePanelController = GetUI<TPanelController>();            // 如果已有界面(之前缓存过的),则不执行任何操作            if (basePanelController != null)            {                if (!basePanelController.canvas.enabled)                {                    basePanelController.canvas.enabled = true;                }                onAsyncGet?.Invoke(basePanelController);                return basePanelController;            }                        ResourceRequest request = Resources.LoadAsync<GameObject>(path);            while (request.isDone == false)            {                await Task.Yield();            }                        GameObject go = request.asset as GameObject;            var basePanel = Instantiate(go).GetComponent<TPanelController>();            if (basePanel != null)            {                InternalOnPanelLoaded(typeof(TPanelController), basePanel, param);                    onAsyncGet?.Invoke(basePanel);                return basePanel;            }            else            {                return null;            }        }                /// <summary>        /// Get Or Create UI asynchronously        /// </summary>        /// <param name="panelType">the panel Type</param>        /// <param name="path">the prefab path</param>        /// <param name="param">opening param</param>        /// <param name="onAsyncGet">if u want to get ui do something,here is for u, which is invoked after BasePanelController.OnLoadSuccess</param>        /// <returns>get panel instance if sync mode load</returns>        public async Task<BasePanelController> OpenUIAsync(Type panelType, string path, IOpenPanelParameter param = null, Action<BasePanelController> onAsyncGet = null)        {            if (!typeof(BasePanelController).IsAssignableFrom(panelType))            {                return null;            }            var basePanelController = GetUI(panelType);            // 如果已有界面(之前缓存过的),则不执行任何操作            if (basePanelController != null)            {                if (!basePanelController.canvas.enabled)                {                    basePanelController.canvas.enabled = true;                }                onAsyncGet?.Invoke(basePanelController);                return basePanelController;            }                        ResourceRequest request = Resources.LoadAsync<GameObject>(path);            while (request.isDone == false)            {                await Task.Yield();            }                        GameObject go = request.asset as GameObject;            var basePanel = Instantiate(go).GetComponent<BasePanelController>();            if (basePanel != null)            {                InternalOnPanelLoaded(panelType, basePanel, param);                    onAsyncGet?.Invoke(basePanel);                return basePanel;            }            else            {                return null;            }        }        /// <summary>        /// Get Or Create UI        /// </summary>        /// <param name="path">the prefab path</param>        /// <param name="param">opening param</param>        /// <typeparam name="TPanelController"></typeparam>        /// <returns>get panel instance if sync mode load</returns>        public TPanelController OpenUI<TPanelController>(string path, IOpenPanelParameter param = null) where TPanelController : BasePanelController        {            TPanelController basePanelController = GetUI<TPanelController>();            // 如果已有界面(之前缓存过的),则不执行任何操作            if (basePanelController != null)            {                if (!basePanelController.canvas.enabled)                {                    basePanelController.canvas.enabled = true;                }                return basePanelController;            }            var go = Resources.Load(path) as GameObject;            if (go != null)            {                var basePanel = GameObject.Instantiate(go).GetComponent<TPanelController>();                uiOpenOrder++;                _registerPanels.Add(typeof(TPanelController), basePanel);                basePanel.OnLoaded(param);                                    basePanel.SetOpenOrder(uiOpenOrder);                return basePanel;            }            return null;        }        /// <summary>        /// Get Or Create UI        /// </summary>        /// <param name="panelType">panel type MUST based on BasePanelController</param>        /// <param name="path">the prefab path</param>        /// <param name="param">opening param</param>        /// <returns>get panel instance if sync mode load</returns>        public BasePanelController OpenUI(Type panelType, string path, IOpenPanelParameter param = null)        {            if (!typeof(BasePanelController).IsAssignableFrom(panelType))            {                return null;            }            var basePanelController = GetUI(panelType);            // 如果已有界面(之前缓存过的),则不执行任何操作            if (basePanelController != null)            {                if (basePanelController != null && !basePanelController.canvas.enabled)                {                    basePanelController.canvas.enabled = true;                }                                return basePanelController;            }            var panelGo = Resources.Load(path) as GameObject;            if (panelGo != null)            {                var basePanel = GameObject.Instantiate(panelGo).GetComponent<BasePanelController>();                uiOpenOrder++;                _registerPanels.Add(panelType, basePanel);                basePanel.OnLoaded(param);                                    basePanel.SetOpenOrder(uiOpenOrder);                return basePanel;            }            return null;        }        public BasePanelController GetUI(Type panelType)        {            if (!typeof(BasePanelController).IsAssignableFrom(panelType))            {                return null;            }            if (_registerPanels.TryGetValue(panelType, out BasePanelController basePanelController))            {                return basePanelController;            }            return null;        }        public TPanelController GetUI<TPanelController>() where TPanelController : BasePanelController        {            Type panelType = typeof(TPanelController);            if (_registerPanels.TryGetValue(panelType, out BasePanelController panel))            {                return (TPanelController)panel;            }                            return null;        }        public bool CloseUI(Type panelType)        {            if (!typeof(BasePanelController).IsAssignableFrom(panelType))            {                return false;            }            BasePanelController baseController = GetUI(panelType);            if (baseController != null)            {                if (panelType == typeof(BasePanelController))     // 标尺界面是测试界面 不用关闭                    return false;                else                    baseController.Close();                return true;            }            return false;        }        public bool CloseUI<TPanelController>() where TPanelController : BasePanelController        {            TPanelController panel = GetUI<TPanelController>();            if (panel != null)            {                panel.Close();                return true;            }            return false;        }                /// <summary>        /// add ui would invoked after create ui automatically, don't need mannually call it in most case        /// </summary>        public void AddUI(BasePanelController panel)        {            if (panel == null)            {                return;            }            panel.transform.SetParent(panel.AttachedParent);            panel.transform.localPosition = Vector3.zero;            panel.transform.localScale = Vector3.one;            panel.transform.localRotation = Quaternion.identity;            panel.gameObject.name = panel.gameObject.name.Replace("(Clone)", "");        }        /// <summary>        /// remove ui would invoked automatically, don't need mannually call it in most case        /// </summary>        public void RemoveUI(BasePanelController panel)        {            if (panel == null)            {                return;            }            Type panelType = panel.GetType();            if (_registerPanels.ContainsKey(panelType))            {                _registerPanels.Remove(panelType);            }            panel.Dispose();        }        /// <summary>        /// take some ui to the most top layer        /// </summary>        /// <param name="panelType"></param>        public void ToppedUI(Type panelType)        {            if (!typeof(BasePanelController).IsAssignableFrom(panelType))            {                return;            }            ToppedUI(GetUI(panelType));        }        /// <summary>        /// take some ui to the most top layer        /// </summary>        /// <param name="panel"></param>        public void ToppedUI(BasePanelController panel)        {            if (panel == null)            {                return;            }            uiOpenOrder++;            panel.SetOpenOrder(uiOpenOrder);        }                /// <summary>        /// open toast panel for tip info        /// </summary>        public void OpenToast(string text, float popupTime = 2.0f)        {            if (!string.IsNullOrEmpty(text) && popupTime > 0)            {                var toast = OpenUI<ToastPanelController>("Toast", new ToastPanelOpenParam(text, popupTime));                if (toast != null)                {                    var rect = toast.transform as RectTransform;                    rect.anchorMin = Vector2.zero;                    rect.anchorMax = Vector2.one;                    rect.anchoredPosition = Vector2.zero;                    rect.sizeDelta = Vector2.zero;                    toast.SetOpenOrder(TOAST_PANEL_SORTING_ORDER);                }            }        }                /// <summary>        /// open toast panel for tip info        /// </summary>        public async Task OpenToastAsync(string text, float popupTime = 2.0f)        {            if (!string.IsNullOrEmpty(text) && popupTime > 0)            {                var toast = await OpenUIAsync<ToastPanelController>("Toast", new ToastPanelOpenParam(text, popupTime));                if (toast != null)                {                    var rect = toast.transform as RectTransform;                    rect.anchorMin = Vector2.zero;                    rect.anchorMax = Vector2.one;                    rect.anchoredPosition = Vector2.zero;                    rect.sizeDelta = Vector2.zero;                    toast.SetOpenOrder(TOAST_PANEL_SORTING_ORDER);                }            }        }        /// <summary>        /// open loading panel that would at the toppest layer and block interaction        /// </summary>        public void OpenLoading()        {            var loadingPanel = OpenUI<LoadingPanelController>("Loading");            if (loadingPanel != null)            {                var rect = loadingPanel.transform as RectTransform;                rect.anchorMin = Vector2.zero;                rect.anchorMax = Vector2.one;                rect.anchoredPosition = Vector2.zero;                rect.sizeDelta = Vector2.zero;                // https://www.reddit.com/r/Unity3D/comments/2b1g1l/order_in_layer_maximum_value/                loadingPanel.SetOpenOrder(LOADING_PANEL_SORTING_ORDER);            }        }                /// <summary>        /// open loading panel that would at the toppest layer and block interaction        /// </summary>        public async Task OpenLoadingAsync()        {            var loadingPanel = await OpenUIAsync<LoadingPanelController>("Loading");            if (loadingPanel != null)            {                var rect = loadingPanel.transform as RectTransform;                rect.anchorMin = Vector2.zero;                rect.anchorMax = Vector2.one;                rect.anchoredPosition = Vector2.zero;                rect.sizeDelta = Vector2.zero;                // https://www.reddit.com/r/Unity3D/comments/2b1g1l/order_in_layer_maximum_value/                loadingPanel.SetOpenOrder(LOADING_PANEL_SORTING_ORDER);            }        }        public void CloseLoading()        {            var loadingPanel = GetUI<LoadingPanelController>();            if (loadingPanel != null)            {                loadingPanel.Close();            }        }        private void InternalOnPanelLoaded(Type tPanelController, BasePanelController basePanel, IOpenPanelParameter param = null)        {            uiOpenOrder++;            _registerPanels.Add(tPanelController, basePanel);            basePanel.OnLoaded(param);                        basePanel.SetOpenOrder(uiOpenOrder);        }                #region external api        public Transform GetUIRootTransform()        {            return _uiRoot.transform;        }        public Camera GetUICamera()        {            return _uiCamera;        }        #endregion    }}
 |