战场UI引发的一宗结构畅想
最近在编写公司项目的战场时,刻意使用Notification将战场逻辑与战场表现还有战场UI拆分为相互独立的三大模块。今天所想记录的就是在开发UI当中设计的一种结构,或许可以值得深入探索总结。
UI是什么?展现战场数据及信息,收集用户操作并向逻辑层、展现层发送通知,还有就是展示UI动画。不得不说我们的UI承担的东西还是挺多的,尤其UI动画,某种意义上它也是展现层的一部分,不过因为是在UI层展示,所以还是划入了UI层,却也发现了一些异常的好处。下面大概说说思路吧。
UI层只有一个总页面,放入我们的结构中来说,他只是一个BattlePage。它的子节点可以有多个MonoBehaviour,但是内部并没有Mono自身的Start、Update等函数,所以全部控制权都放在了BattlePage中。所有的子节点都定义为SubPage的派生类。
public class SubPage : MonoBehaviour { public virtual void FirstOpen() { } public virtual void Tick(float delta) { } public virtual void FinalClose() { } }
BattlePage自身包含页面的Open、Close、Update等方法,所以核心需要做的就是这么几点事了:
Open函数是页面第一次打开时候调用,所以在这里就需要通过GetComponentsInChildren获取子节点中所有的SubPage,并进行存储。之后调用所有SubPage的FirstOpen函数。
Close函数是页面最终关闭时候调用,所以在这里就需要对记录的所有SubPage执行它们的FinalClose函数。
Update函数则只需要简单执行SubPage的Tick方法即可,同时传入deltaTime参数。
public class BattlePage : Page { List<SubPage> allSubPages; public override void PageOpen () { allSubPages = new List<SubPage> (GetComponentsInChildren<SubPage> ()); for (int i = 0, imax = allSubPages.Count; i < imax; i++) { allSubPages[i].FirstOpen (); } } public override void PageClose () { for (int i = 0, imax = allSubPages.Count; i < imax; i++) { allSubPages[i].FinalClose (); } } private void Update () { float deltaTime = Time.deltaTime; for (int i = 0, imax = allSubPages.Count; i < imax; i++) { allSubPages[i].Tick (deltaTime); } } }
如此设计,BattlePage只是一个页面的管理器,内部则不需要再关注具体细节。而且一旦需要添加新的模块,只需要继承SubPage并添加到BattlePage成为其子节点,便可只关注内部具体实现。
那么SubPage的子类们究竟需要实现一些什么呢?由于采用MVC结构,并且整体是使用Notification实现,所以SubPage只需要实现这么几件事就可以:1.在FirstOpen中注册观察者及观察消息和对应的处理函数;2.在FinalClose中移除观察者;3.实现当前SubPage的具体UI展现逻辑。以我们项目中某英雄角色放大招之前的动画为例:页面在进入战场时注册大招观察者,收到消息即开始展示该英雄的大头贴动画,动画由SubPage自身的Tick实现,展示结束则广播展示结束通知消息,当战场关闭时便释放观察者。
public class HeroUIAnimPage : SubPage { public override void FinalClose() { NotificationCenter.Default.RemoveObserver(this); } public override void FirstOpen() { NotificationCenter.Default.AddObserver(this, BeginPlay, "PlayHeroAnim", null); } private void BeginPlay(Notification notification) { // Begin Play UI Anim } public override void Tick(float delta) { // Play UI Anim } }
经过现有开发阶段的验证,针对当前需求,采用此种开发模式效率高,且页面逻辑之间不存在耦合,修改也很快。
所以如果有人看到,希望大家一起交流

浙公网安备 33010602011771号