3.流程示例——ProcedureMenu
本文 Game Framework 版本:3.1.0
本文 Unity3D 版本:2017.3
转载请注明,原文地址:http://www.benmutou.com/archives/2495
文章来源:笨木头与游戏开发
这篇我们通过ProcedureMenu这个流程,大致了解Game Framework这个框架的基本玩耍方式。
1.生命周期
ProcedureMenu重写了以下三个函数:
很明显,这是一个基础流程所具备的三个生命周期,进入、每帧更新、离开。
我们一个个来看吧。
2.OnEnter
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
m_StartGame = false;
GameEntry.UI.OpenUIForm(UIFormId.MenuForm, this);
}
OnEnter做了以下事情:
2.1.订阅事件(GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);)
Event也是框架的基础组件之一,订阅事件的方式为传入一个事件id,以及事件发生时要执行的函数。
从代码中可以看出来,作者对不同的事件进行了封装,比如OpenUIFormSucessEventArgs为【打开界面成功】的事件。
这和我自己一直使用的事件订阅方式有点不同,我都是把不同的事件ID定义成枚举或者一堆常量,直接把事件封装为一个类,有点新奇。
不过,我们暂时不深入研究,毕竟只是入门解读。
2.2.游戏开始标记设为false(m_StartGame = false;)
这个倒没什么能解释的了。
2.3.打开菜单UI(GameEntry.UI.OpenUIForm(UIFormId.MenuForm, this);)
因为UI模块的OpenUIForm的第一个参数需要一个int类型,而StarForce项目里给UI定的id值是一个枚举类型。这个扩展函数只不过是把枚举转换为int。
关于打开菜单这一步操作,主要有两个地方要关注,分别是uiFormId和userData。
uiFormId:
打开UI也是框架的基础功能之一(UI模块),打开UI的方式倒是很容易接受,传入UI的唯一
id(自定义的值,int类型)。
不过,这里的OpenUIForm函数并不是框架底层函数,而是StarForce封装过的扩展函数。
但是,目前我们只需要知道可以这样打开UI就好,以后专门研究UI模块的时候再和大家分享。
userData:
另外,还有第二个参数,这是一个自定义数据,在UI成功打开时,会触发UI打开成功事件(就是我们之前订阅的那个)。
触发事件时,会传递一个数据过来,这个数据就是我们在OpenUIForm里传递进去的userData。
说的简单点的话,就是,我们事先传进去一个值,事件发生时,再把这个值传回给我们。
在某些情况下很有用,但先不管。
3.触发事件
在讲解下一个生命周期函数之前,我们先来看看打开菜单成功时触发的事件是怎么样的。
还记得2.1里订阅的那个事件吗?不记得的话,我就不管你了(●ˇ∀ˇ●)
我们订阅的事件回调函数是这样的:
private void OnOpenUIFormSuccess(object sender, GameEventArgs e)
{
OpenUIFormSuccessEventArgs ne = (OpenUIFormSuccessEventArgs)e;
if (ne.UserData != this)
{
return;
}
m_MenuForm = (MenuForm)ne.UIForm.Logic;
}
参数e就是事件发生时传递过来的数据,其中包含了我们传出去的UserData数据。
然后就是给m_MenuForm赋值了,事件参数里还包含了UI的信息,m_MenuForm赋值的是负责处理UI逻辑的对象。
至于这个对象是干什么的,我也不知道,我猜是对UI进行打开、关闭一类的操作吧。
4.OnUpdate
protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
if (m_StartGame)
{
procedureOwner.SetData<VarInt>(Constant.ProcedureData.NextSceneId, (int)SceneId.Main);
procedureOwner.SetData<VarInt>(Constant.ProcedureData.GameMode, (int)GameMode.Survival);
ChangeState<ProcedureChangeScene>(procedureOwner);
}
}
至于OnUpdate函数,估计和Unity的Update是对应的(可能封装了一些操作)。
OnUpdate只做了一件事情——点击开始游戏后(m_StartGame为true),切换到Main场景。
木头大概看了一会代码,框架对于场景的切换也是用到流程。
框架利用有限状态机,用于切换不同的流程,不同的流程就做不同的事情。
如以上代码中的【ChangeState<ProcedureChangeScene>(procedureOwner)】,就是把流程切换至ProcedureChangeScene,而ProcedureChangeScene是一个专门用于切换场景的流程。
procedureOwner参数可以理解为下一个流程所需要的一些配置数据,这里的procedureOwner配置了切换场景所需的场景ID及游戏模式,这些数据是自定义的,你可以传任意的配置数据。
至于不同的场景是怎么和不同的流程对应起来的?木头暂时发现的是…直接判断。
比如在ProcedureChangeScene里,如果判断到要切换的场景是菜单场景,则把流程切换至菜单流程。
至于自动绑定流程和场景的方式,暂时没发现。
目前的猜测是,流程和场景变数比较大,无法很好地实现自动绑定(我猜)。
更多的我就不深入了,以后再慢慢研究。
5.OnLeave
protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
{
base.OnLeave(procedureOwner, isShutdown);
GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
if (m_MenuForm != null)
{
m_MenuForm.Close(isShutdown);
m_MenuForm = null;
}
}
最后就是OnLeave,这个函数是离开当前流程的时候调用的。
基本上就是做释放资源的操作,比如这里是取消订阅事件、关闭菜单UI。
6.唠叨一下
经过以上的讲解,其实大家只要记住其中两点即可:
a.Game Framework框架是用流程(Procedure)来处理所有事情的,不同的流程负责不同的工作。
比如菜单流程,负责处理打开、关闭菜单的操作;切换场景流程,负责切换不同的场景。
b.流程的切换是用有限状态机来实现的。
c.切换场景后,初始入口场景不会卸载,因此所有的基础组件功能都仍然生效。
到目前为止,我们只是知道了主场景在哪、菜单怎么出现、怎么进入真正的游戏场景。
下一篇,我们一起来看看游戏场景里做了什么事情。