在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小时内删除。
发表评论