笨木头  2018-02-07 17:10     Unity3D,Game Framework     阅读(18524)     评论(2)
转载请注明,原文地址: http://www.benmutou.com/archives/2495
文章来源:笨木头与游戏开发
本文 Game Framework 版本:3.1.0

本文 Unity3D 版本:2017.3

更多GF教程和实例:https://github.com/mutouzdl/gameframework_demo.git

 
转载请注明,原文地址: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.游戏开始标记设为falsem_StartGame = false;

这个倒没什么能解释的了。

 

2.3.打开菜单UIGameEntry.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.切换场景后,初始入口场景不会卸载,因此所有的基础组件功能都仍然生效。

到目前为止,我们只是知道了主场景在哪、菜单怎么出现、怎么进入真正的游戏场景。

下一篇,我们一起来看看游戏场景里做了什么事情。

2 条评论
  • 吃豆人 2020-01-17 14:28:47

    记住两点即可:
    a.
    b.
    c.
    13回复
    • 博主 笨木头 2020-01-18 07:41:24

      这不,弄点意外的事情,大家印象就特别深刻(*/ω\*)
      4回复
发表评论
粤ICP备16043700号

本博客基于 BlazorAnt Design Blazor 开发