GameUI搭建


- HP血条是通过动态增删LifeItem图片实现的
- 右下角为护盾和炸弹,需要添加特效,还需要添加左手右手模式。
在Prefab文件夹内,新建UI文件夹,将UI的Prefab全部转移进去,并修改Pathes
里面的路径
Pathes
中添加UIPrefab路径和创建GameUIController
、GameUIView
的部分略。注意要创建在Scripts——UI——GameUI文件夹内。
Const
在Const中添加玩家最大生命值常量,以及LifeItem最大显示数量。
1 2 3
| public const int LIFE_MAX = 100; public const int LIFE_ITEM_NUM = 10;
|
GameUIView
只有根节点上的UI脚本才会使用“View”做结尾。
1 2 3 4 5 6 7 8
| [BindPrefab(Pathes.GAMEUI_VIEW,Consts.BIND_PREFAB_PRIORITY_VIEW)] public class GameUIView : ViewBase { protected override void InitChild() { UIUtil.Get("Life").AddCo<Life>(); } }
|
GameUIController
1 2 3 4 5 6 7 8
| [BindPrefab(Pathes.GAMEUI_VIEW,Consts.BIND_PREFAB_PRIORITY_CONTROLLER)] public class GameUIController : ControllerBase { protected override void InitChild() { transform.Find("Life").gameObject.AddComponent<LifeController>(); } }
|
Life
Life
脚本需要动态挂载在GameUI——Life节点上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| using System.Collections.Generic; using UnityEngine;
public class Life : ViewBase, IReceiver { private List<LifeItem> _items; protected override void InitChild() { _items = new(); InitItem(); UpdateLife(); } public override void Show() { base.Show(); MessageMgr.Instance.AddListener(MsgEvent.EVENT_HP, this); } public override void Hide() { base.Hide(); MessageMgr.Instance.RemoveListener(MsgEvent.EVENT_HP, this); } private void InitItem() { GameObject item; for (int i = 0; i < Consts.LIFE_ITEM_NUM; i++) { item = LoadMgr.Instance.LoadPrefabAndInstantiate(Pathes.LIFE_ITEM,transform); item.name = i.ToString(); _items.Add(item.AddComponent<LifeItem>()); } } private void UpdateLife() { UIUtil.Get("Value").SetText(GameModel.Instance.Life); }
public void ReceiveMessage(params object[] args) { UpdateLife(); } }
|
Life
脚本继承IReceiver
,接入消息系统。
通过InitItem
动态添加LifeItem。
每次动态生成一个LifeItem,都修改一下生成的这个Item的name,把它的id作为name,传给LifeItem
UpdateLife
方法交给消息系统来更新,消息系统的实现在下一节。
LifeController
LifeController
1 2 3 4 5 6
| public class LifeController : ControllerBase { protected override void InitChild() { } }
|
GameModel
在Scripts——Model文件夹内新建GameModel
脚本,这个脚本存储运行时的玩家生命值和得分数据等。
1 2 3 4 5 6
| public class GameModel : NormalSingleton<GameModel> { public int Life { get; set; } public int Score { get; set; } public int Stars { get; set; } }
|
LifeItem
LifeItem
是动态加载到Life节点下的LifeItem预制体上挂载的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| using UnityEngine;
public class LifeItem : ViewBase, IReceiver { private int _lifeMin; protected override void InitChild() { int id = int.Parse(transform.name); SetItemPos(id); _lifeMin = GetLifeMin(id); } public override void Show() { base.Show(); MessageMgr.Instance.AddListener(MsgEvent.EVENT_HP, this); } public override void Hide() { base.Hide(); MessageMgr.Instance.RemoveListener(MsgEvent.EVENT_HP, this); } private int GetLifeMin(int id) { int eachLife = Consts.LIFE_MAX / Consts.LIFE_ITEM_NUM; return id * eachLife; } private void SetItemPos(int id) { RectTransform rectTrans = transform.GetRect(); float width = rectTrans.rect.height; Vector2 pos = rectTrans.anchoredPosition; pos.x = width / 2 + width * id; rectTrans.anchoredPosition = pos; } public void ReceiveMessage(params object[] args) { if (GameModel.Instance.Life < _lifeMin) { Hide(); } } }
|
每个LifeItem都是代表10点生命值的块,注意每个LifeItem的Prefab都旋转了90度,所以我们通过Height值来计算下一个LifeItem的位置。
LifeItem
继承IReceiver
,接入消息系统,使用消息系统来更新自己的显示。消息系统在下一节。