1. 程式人生 > >Unity 客戶端框架(六):UI框架

Unity 客戶端框架(六):UI框架

public abstract class BaseUI : MonoBehaviour
    {
        #region 快取

        private Transform _CachedTransform;
        public Transform cachedTransform
        {
            get
            {
                if(!_CachedTransform)
                {
                    _CachedTransform = this.transform;
                }
                return _CachedTransform;
            }
        }

        private GameObject _CachedGameobject;
        public GameObject cachedGameobject
        {
            get
            {
                if (!_CachedGameobject)
                {
                    _CachedGameobject = this.gameObject;
                }
                return _CachedGameobject;
            }
        }

        #endregion

        #region Type && State

        protected EnumObjectState state = EnumObjectState.None;

        public event StateChangedEvent StateChanged;

        public EnumObjectState State
        {
            get
            {
                return this.state;
            }
            set
            {
                if(value != state)
                {
                    EnumObjectState oldState = value;
                    state = value;
                    if (null != StateChanged)
                        StateChanged(this, state, oldState);
                }
            }
        }

        public abstract EnumUIType GetUIType();

        #endregion

        public virtual void SetDepthToTop() { }

        void Start()
        {
            OnStart();
        }

        void Awake()
        {
            this.State = EnumObjectState.Initial;
            OnAwake();
        }

        void Update()
        {
            if (EnumObjectState.Ready == State)
                OnUpdate(Time.deltaTime);
        }

        public void Release()
        {
            this.State = EnumObjectState.Closing;
            //GameObject.Destroy(cachedGameobject);
            ObjPool.Instance.OnReturnObj(cachedGameobject);
            OnRelease();
        }

        protected virtual void OnStart()
        {

        }

        protected virtual void OnAwake()
        {
            this.State = EnumObjectState.Loading;
            this.OnPlayOpenUIAudio();
        }

        protected virtual void OnUpdate(float dletaTime)
        {

        }

        protected virtual void OnRelease()
        {
            this.OnPlayCloseUIAudio();
        }

        protected virtual void OnPlayOpenUIAudio()
        {

        }

        protected virtual void OnPlayCloseUIAudio()
        {

        }

        protected virtual void SetUI(params object[] uiParams)
        {
            this.State = EnumObjectState.Loading;
        }

        protected virtual void OnLoadData()
        {

        }

        public void SetUIWhenOpening(params object[] uiParams)
        {
            SetUI(uiParams);
            CoroutineInstance.Instance.StartCoroutine(AsyncOnLoadData());
        }

        private IEnumerator AsyncOnLoadData()
        {
            yield return new WaitForSeconds(0);
            if(this.State == EnumObjectState.Loading)
            {
                this.OnLoadData();
                this.State = EnumObjectState.Ready;
            }
        }


    }
 public class UIManager : Singleton<UIManager>
    {

        #region UIInfoData

        class UIInfoData
        {
            public EnumUIType UIType { get; private set; }

            public Type ScriptType { get; private set; }

            public string Path { get; private set; }

            public object[] UIParams { get; private set; }

            public UIInfoData(EnumUIType _uiType, string _path, params object[] _uiParams)
            {
                this.UIType = _uiType;
                this.Path = _path;
                this.UIParams = _uiParams;
                this.ScriptType = UIPathDefines.GetUIScriptByType(this.UIType);
            }
        }

        #endregion

        private Dictionary<EnumUIType, GameObject> dicOpenedUIs = null;

        private Stack<UIInfoData> stackOpeningUIs = null;

        public override void Init()
        {
            dicOpenedUIs = new Dictionary<EnumUIType, GameObject>();
            stackOpeningUIs = new Stack<UIInfoData>();
        }

        #region Get
        
        public T GetUI<T>(EnumUIType _type) where T : BaseUI
        {
            GameObject _retObj = GetUIObject(_type);
            if (_retObj != null)
                return _retObj.GetComponent<T>();
            return null;
        }
        
        public GameObject GetUIObject(EnumUIType _type)
        {
            GameObject _retObj = null;
            if(!dicOpenedUIs.TryGetValue(_type,out _retObj))
                throw new Exception("dicOpenedUIs TryGetValue Failure! _uiType :" + _type.ToString());
            return _retObj;
        }

        #endregion

        #region Preload

        public void PreloadUI(EnumUIType[] _uiTypes)
        {
            for (int i = 0; i < _uiTypes.Length; i++)
            {
                PreloadUI(_uiTypes[i]);
            }
        }


        public void PreloadUI(EnumUIType _uiType)
        {
            string path = UIPathDefines.UI_PREFAB + _uiType.ToString();
            ResManager.Instance.Load(path);
            
        }

        #endregion

        #region Open
       
        public void OpenUI(EnumUIType[] uiTypes)
        {
            OpenUI(false, uiTypes, null);
        }

       
        public void OpenUI(EnumUIType uiType, params object[] uiObjParams)
        {
            EnumUIType[] uiTypes = new EnumUIType[1];
            uiTypes[0] = uiType;
            OpenUI(false, uiTypes, uiObjParams);
        }

        public void OpenUICloseOthers(EnumUIType[] uiTypes)
        {
            OpenUI(true, uiTypes, null);
        }


        public void OpenUICloseOthers(EnumUIType uiType, params object[] uiObjParams)
        {
            EnumUIType[] uiTypes = new EnumUIType[1];
            uiTypes[0] = uiType;
            OpenUI(true, uiTypes, uiObjParams);
        }

      
        private void OpenUI(bool _isCloseOthers, EnumUIType[] _uiTypes, params object[] _uiParams)
        {
            // Close Others UI.
            if (_isCloseOthers)
            {
                CloseUIAll();
            }

            // push _uiTypes in Stack.
            for (int i = 0; i < _uiTypes.Length; i++)
            {
                EnumUIType _uiType = _uiTypes[i];
                if (!dicOpenedUIs.ContainsKey(_uiType))
                {
                    string _path = UIPathDefines.UI_PREFAB + _uiType.ToString();
                    stackOpeningUIs.Push(new UIInfoData(_uiType, _path, _uiParams));
                }
            }

            // Open UI.
            if (stackOpeningUIs.Count > 0)
            {
                  CoroutineInstance.Instance.StartCoroutine(AsyncLoadData());
            }
        }


        private IEnumerator<int> AsyncLoadData()
        {
            UIInfoData _uiInfoData = null;
            GameObject _prefabObj = null;
            //GameObject _uiObject = null;

            if (stackOpeningUIs != null && stackOpeningUIs.Count > 0)
            {
                do
                {
                    _uiInfoData = stackOpeningUIs.Pop();

                    //_prefabObj = ResManager.Instance.Load(_uiInfoData.Path);
                    string[] str = _uiInfoData.Path.Split('/');
                    _prefabObj = ObjPool.Instance.OnGetObj(str[1], str[0]);
                    _prefabObj.transform.SetParent(null);


                    if (_prefabObj != null)
                    {
                        //_uiObject = NGUITools.AddChild(Game.Instance.mainUICamera.gameObject, _prefabObj as GameObject);
                        //_uiObject = MonoBehaviour.Instantiate(_prefabObj) as GameObject;
                        BaseUI _baseUI = _prefabObj.GetComponent<BaseUI>();
                        if (null == _baseUI)
                        {
                            _baseUI = _prefabObj.AddComponent(_uiInfoData.ScriptType) as BaseUI;
                        }
                        if (null != _baseUI)
                        {
                            _baseUI.SetUIWhenOpening(_uiInfoData.UIParams);
                        }
                        dicOpenedUIs.Add(_uiInfoData.UIType, _prefabObj);
                    }

                } while (stackOpeningUIs.Count > 0);
            }
            yield return 0;
        }

        #endregion

        #region Close

        public void CloseUI(EnumUIType _uiType)
        {
            GameObject _uiObj = null;
            if (!dicOpenedUIs.TryGetValue(_uiType, out _uiObj))
            {
                Debug.Log("dicOpenedUIs TryGetValue Failure! _uiType :" + _uiType.ToString());
                return;
            }
            CloseUI(_uiType, _uiObj);
        }

        public void CloseUI(EnumUIType[] _uiTypes)
        {
            for (int i = 0; i < _uiTypes.Length; i++)
            {
                CloseUI(_uiTypes[i]);
            }
        }


        public void CloseUIAll()
        {
            List<EnumUIType> _keyList = new List<EnumUIType>(dicOpenedUIs.Keys);
            foreach (EnumUIType _uiType in _keyList)
            {
                GameObject _uiObj = dicOpenedUIs[_uiType];
                CloseUI(_uiType, _uiObj);
            }
            dicOpenedUIs.Clear();
        }

        private void CloseUI(EnumUIType _uiType, GameObject _uiObj)
        {
            if (_uiObj == null)
            {
                dicOpenedUIs.Remove(_uiType);
            }
            else
            {
                BaseUI _baseUI = _uiObj.GetComponent<BaseUI>();
                if (_baseUI != null)
                {
                    _baseUI.StateChanged += CloseUIHandler;
                    _baseUI.Release();
                }
                else
                {
                    GameObject.Destroy(_uiObj);
                    dicOpenedUIs.Remove(_uiType);
                }
            }
        }


        private void CloseUIHandler(object _sender, EnumObjectState _newState, EnumObjectState _oldState)
        {
            if (_newState == EnumObjectState.Closing)
            {
                BaseUI _baseUI = _sender as BaseUI;
                dicOpenedUIs.Remove(_baseUI.GetUIType());
                _baseUI.StateChanged -= CloseUIHandler;
            }
        }
        #endregion

    }




2017.3.12更新  補上列舉程式碼