在ILRuntime的基础上,搭建⼀个简单的UI系统(⼀)UIPanel 前⾔
在前⾯三篇⽂章中,我们简单的搭建好了ILRuntime的使⽤环境,然⽽还并没有实现具体的功能。所以在这篇⽂章中我们⾸先简单的实现下UI模块相关的功能。(暂时不考虑AB包系统,系统等等,同时本篇先是简单的实现UI显⽰以及跳转,更多的功能在后续进⾏补充)
思路
在实现代码前,我们⾸先要清楚我们的需求,UI系统的功能⼤致有加载UI,显⽰UI,跳转UI,UI层级管理等等。
通常我们会把⼀个完整的界⾯当成⼀个整体(⼀个prefab),⽐如登陆页⾯,主页⾯,商城页⾯等等,它们可以都继承于⼀个基类(暂定为UIPanel),主要功能就是显⽰隐藏界⾯,获取界⾯内的组件等等。
在⼀些界⾯中往往有些组件需要我们单独管理的,⽐如⽤户信息栏,商城物品的Item等,它们也可以都继承于⼀个基类(暂定为UIView,同时UIPanel继承于UIView),主要功能就是加载prefab,数据的显⽰等。
然后我们建⽴两个管理器,UIPanelManager和UIViewManager分别进⾏管理。UIPanelManager主要管理界⾯的显⽰隐藏和跳
转,UIViewManager主要维护UIView的⽣命周期。
由于我们⽣成⼀个UIPanel的⼦类就需要加载对应的Prefab,⽐如要显⽰登陆界⾯,我们要实例化LoginPanel,同时加载
LoginPanel.prefab,那么我们如何在实例化UIPanel的时候就得知其对应的Prefab是哪个呢,我们可以使⽤Attribute功能来实现,在每个UIPanel中进⾏配置对应的prefab的名称,具体代码看下⽂。
简单效果如图
代码实现
由于UI系统的逻辑后期变动会⽐较⼤,也容易出BUG,更新也会很频繁,所以我们将这部分的相关代码全部放在Hotfix部分,以便后续维护更新。⽬录结构⼤致如下
⾸先创建⼀个IView接⼝,⽤于⽣命周期
1namespace Hotfix.UI
2{
3    public interface IView
4
5    {
6        //初始化,只在prefab被创建的时候执⾏⼀次
7        void Init();
8        //每次界⾯显⽰的时候执⾏
9        void Show();
10        void Update();
11        void LateUpdate();
12        void FixedUpdate();
13        //界⾯被隐藏的时候执⾏,再次显⽰会调⽤Show⽅法
14        void Hide();
15        //销毁的时候执⾏
16        void Destroy();
17    }
18}
然后创建UIView类实现IView接⼝,主要功能是加载和销毁gameobject,并在Show和Hide⽅法中进⾏显⽰和隐藏。
1namespace Hotfix.UI
2{
3    public class UIView : IView
4    {
5        //需要加载的prefab的路径,也作为唯⼀标识符
6        public string url { private set; get; }
7
8        public GameObject gameObject { private set; get; }
9        public Transform transform { private set; get; }
10        public RectTransform rectTransform { private set; get; }
11
12        //是否加载完成
13        public bool isLoaded { get { return gameObject != null; } }
14
15        //是否显⽰
16        public bool isVisible
17        {
18            get
18            get
19            {
20                return isLoaded && gameObject.activeSelf;
21            }
22            set
23            {
24                if (isLoaded)
25                    gameObject.SetActive(value);
26            }
27        }
28
29        //若为true,将在下⼀帧销毁gameobject
30        internal bool isWillDestroy;
31
32        public UIView(string url)
33        {
34            this.url = url;
35        }
36
37        public virtual void Init()
38        {
39            isVisible = false;
40        }
41
42        public virtual void Show()
43        {
44            isVisible = true;
45        }
46
47        ......
view ui框架
48
49        public virtual void Hide()
50        {
51            isVisible = false;
52        }
53
54        public virtual void Destroy()
55        {
56            isWillDestroy = true;
57            if (isVisible)
58            {
59                Hide();
60            }
61        }
62
63        //销毁gameobject
64        public void DestroyImmediately()
65        {
66            if (!isWillDestroy)
67            {
68                Destroy();
69            }
70            GameObject.Destroy(gameObject);
71            gameObject = null;
72            transform = null;
73            rectTransform = null;
74        }
75
76        //加载prefab
77        public virtual void Load(Action callback = null)
78        {
79            gameObject = GameObject.Instantiate(Resources.Load(url)) as GameObject;
80            if (gameObject != null)
81            {
82                transform = ansform;
83                rectTransform = gameObject.GetComponent<RectTransform>();
83                rectTransform = gameObject.GetComponent<RectTransform>();
84
85                Init();
86                callback?.Invoke();
87            }
88        }
89    }
90}
然后编写UIPanel,继承于UIView
1namespace Hotfix.UI
2{
3    public class UIPanel : UIView
4    {
5        //UIPanel间的⾃定义传递数据
6        public object data;
7
8        //前⼀个UIPanel,⽤于隐藏⾃⼰的时候,Show前者
9        public UIPanel previousPanel;
10
11        public UIPanel(string url) : base(url)
12        {
13        }
14
15        public override void Destroy()
16        {
17            base.Destroy();
18            previousPanel = null;
19        }
20    }
21}
接着我们编写UIViewManager,⽤于管理UIView,主要⽤于⽣成和获取UIView,管理所有UIView的⽣命周期
1using Hotfix.UI;
2using System;
3using System.Collections.Generic;
4
5namespace Hotfix.Manager
6{
7    public class UIViewManager : ManagerBase<UIViewManager>
8    {
9        //存放所有在场景中的UIView
10        List<UIView> m_UIViewList;
11
12        public override void Init()
13        {
14            base.Init();
15            m_UIViewList = new List<UIView>();
16        }
17
18        public override void Update()
19        {
20            base.Update();
21
22            for (int i = 0; i < m_UIViewList.Count; i++)
23            {
24                //销毁UIView
25                if (m_UIViewList[i].isWillDestroy)
26                {
27                    m_UIViewList[i].DestroyImmediately();
28                    m_UIViewList.RemoveAt(i);
29                    i--;
30                    continue;
31                }
32
33                if (m_UIViewList[i].isVisible)
34                {
35                    m_UIViewList[i].Update();
36                }
37            }
38        }
39
40        ......
41
42
43        //创建UIView
44        public UIView CreateView(Type type, params object[] args)
45        {
46            UIView view = Activator.CreateInstance(type, args) as UIView;
47            m_UIViewList.Add(view);
48            return view;
49        }
50
51        public void DestroyAll()
52        {
53            for (int i = 0; i < m_UIViewList.Count; i++)
54                m_UIViewList[i].Destroy();
55        }
56    }
57}
接下来是⽐较重要的⼀点了,在前⾯的UIView当中,我们通过url这个路径来加载prefab,那么我们实例化⼀个UIPanel的时候,⽐如LoginPanel,MainPanel,我们如何仅仅通过Type知道每个UIPanel对应的prefab,即url的值。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。