[Game Framework之StarForce解读]05.玩家飞机逻辑处理类

笨木头  2018-02-27 17:15   Game Framework,Unity3D   阅读(2,257)   4条评论

本文 Game Framework 版本:3.1.0

本文 Unity3D 版本:2017.3

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

 

转载请注明,原文地址:http://www.benmutou.com/archives/2521
文章来源:笨木头与游戏开发

通过上一篇的研究,我们已经了解到玩家飞机和怪物是怎么加载出来的(根据配置id读取配置文件,创建实体)。

我们来回忆一下,玩家飞机是怎么创建的:GameEntry.Entity.ShowMyAircraft

现在,为了知道玩家飞机的逻辑是在哪里处理,我跟进了ShowMyAircraft函数,又发现了框架作者的秘密。

1.GameEntry.Entity来源

ShowMyAircraft函数是通过GameEntry.Entity调用的,那我们自然要先知道这里的Entity是什么东西。

如果大家还记得最开始的文章的话,应该对GameEntry不陌生——它是游戏初始化入口。

在GameEntry的InitBuiltinComponents函数里,对Enitity属性进行了赋值:

Entity = UnityGameFramework.Runtime.GameEntry.GetComponent<EntityComponent>();

我们现在知道了,Entity是一个EntityComponet类型的对象。

至于EntityComponent,它是游戏组件,继承了GameFrameworkComponent,它在初始化的时候会调用GameEntry.RegisterComponent(this)注册自身:

必须是先进行了注册的组件,UnityGameFramework.Runtime.GameEntry.GetComponent才能获取到。

不过,现在不理解也没关系,我们只要知道,GameEntry.Entity是什么就好了。

注意,UnityGameFramework.Runtime.GameEntry和StarForce.GameEntry不是同一个对象,只是类名相同而已。

2.调用顺序

ShowMyAircraft函数进行了很多层的封装,不得不吐槽一下,一个demo做得这么复杂,我对框架的推广有点担忧…当然,并不是说这样不好,只是觉得针对demo级别,有点繁琐而已。

首先调用的是EntityExtension里的ShowMyAircraft函数,这里主要是为了从配置文件中加载飞机实体的配置数据(上一篇讲解过了)。

接下来才是调用EntityComponent的ShowEntity函数:

EntityComponent的ShowEntity函数又调用了IEntityManager的ShowEntity函数,留意最后一个参数(ShowEntityInfo),这个参数最终会通过实体对象的生命周期函数传回来。

这里的IEntityManager是什么?我又得给大家解释一下了:

3.IEntityManager

EntityComponent有一个类型为IEntityManager的属性,m_entityManager。

IEntityManager是一个接口,在EntityComponent的Awake里进行了初始化:

m_EntityManager = GameFrameworkEntry.GetModule<IEntityManager>();

具体GetModule是做了什么事情,我们暂时不深入了解,只要知道,它是用于获取游戏框架模块的,这里返回的对象是EntityManager(实体管理器)。

4.EntityManagerShowEnity函数

于是,我们又回到ShowEntity函数,EntityManager的ShowEntity函数主要做了下面几件事情:

a.根据配置数据,创建实体(从预制体创建)

b.调用实体对象的OnInit、OnShow生命周期函数,这里会把第2步提到的最后一个参数(new ShowEntityInfo(entityLogicType, userData))传递回来

c.还做了一些其他操作,我们暂时忽略

5.DefaultEntityHepler

等等,我们说了这么久,好像还没说到本篇的主题——飞机逻辑处理类

是的,为了知道逻辑处理类是如何绑定到实体上的,我们必须先了解实体是怎么创建的。

现在我们已经知道实体如何创建了,接下来,是最后一步,逻辑处理类是怎么和创建的实体对象关联起来的?

在EntityComponent类的Awake函数中,我们创建了EntityManager对象:

在Start函数里,还绑定了一个EntityHelper对象,这个EntityHelper对象就是实体管理器具体创建实体时要利用的工具类。代码比较多,我只截取其中一部分:

其中m_EntityHelperTypeName是这个Helper类的类型名字:

所以,我们知道了,EntityManage绑定的EntityHelper对象是DefaultEntityHelper。

DefaultEntityHelper是自定义的一个类,继承了EntityHelperBase。

 

如果以上你都没有看懂,那么,全部忽略吧(旁白:那我到底是为了什么要看你的文章啊喂!

我们只要知道,最终EntityManager创建实体的时候会调用DefaultEntityHelper的CreateEntity函数即可。

 

但是,到此为止还是不能找到逻辑处理类在哪里绑定的,我们还要继续研究。(旁白:说好的最后一步呢?!

6.最终的DefaultEntityHelperCreateEntity函数

经过重重难关,我们终于找到了逻辑处理类是如何与实体对象绑定的,那就是DefaultEntityHelper的CreateEntity函数:

entityInstance即为实体对象,但这个对象是由框架底层创建,这个不是重点。

重点是最后一行代码,就是这一行代码,把Entity对象添加到了实体对象身上。

你以为这样就结束了吗?不,还有一步。(旁白:大家别拦着我!

7.最终终极真的是最后一个关键地方——Entity

我们先别激动,虽然我们已经知道了Entity会绑定到创建的实体对象(GameObject)上(旁白:不,我有点懵,我不知道,实体对象是什么?Entity又是什么?!)。

如果大家不是很明白实体对象和Entity的关系,那我举个简单的例子:在Unity的IDE里创建一个空的GameObject对象,然后把脚本Entity拖到这个对象身上。

这就是我所说的实体对象和Entity的关系了。

 

好,我们再回忆一下,EntityManager的ShowEntity函数做了哪些事情:

a.根据配置数据,创建实体(从预制体创建)

b.调用实体对象的OnInit、OnShow生命周期函数,这里会把第2步提到的最后一个参数(new ShowEntityInfo(entityLogicType, userData))传递回来

各位,对不起,其实之前说的第b步,是我瞎掰的,实际上并不是调用实体对象生命周期函数,而是调用实体对象所绑定的脚本(Entity)的生命周期函数。

 

EnityManager的ShowEntity函数,会执行下面的代码:

首先是调用了m_EntityHelper(在这里就是DefaultEntityHelper类)的CreateEntity函数,这个函数返回的并不是一个GameObject,而是一个IEntity类型,具体到DefaultEntityHelper的CreateEntity函数,就是返回Entity对象。

 

所以,准确的说法是,在EntityManage的ShowEntity执行的过程中,会调用Entity的生命周期函数。

好,这个是重点,也是我们这篇文章要做的第一步(旁白:我觉得我第一步要做的就是关掉这篇文章)。

 

接下来就是要看看Entity的OnInit函数做了什么事情了:

为了更清晰地看逻辑,我删掉了很多代码,留下了三个关键的地方。

Entity的OnInit函数基本上就做一件事情——把逻辑处理类绑定到实体对象身上。

至于逻辑处理类的类型,是在一开始就通过参数传递的(EntityExtension的ShowMyAircraft函数):

8.结束

至于MyAircraft做了什么事情,那就是我们自己的事情了,它就是处理逻辑的,想怎么处理是我们自己定的。

这个Demo里无非就是控制移动、发射子弹,只是做的封装比较多。

时间关系,我就不继续介绍了。

 

至此,Game Framework的Demo项目StarForce的介绍,到此为止。

希望这系列的文章能稍微让大家了解了Game Framework的基础思路。

可能Demo中还有很多框架的使用细节没有说到,但我个人也是没有实际使用过这个框架,所以不想太过细致地去研究这个Demo,我希望未来在使用的过程中再去了解更多细节。

 

有机会的话,我会用尽量少的封装写一个Demo,这样学习起来会更加方便。

嗯,有机会的话……旁白:所以为什么要用省略号,感觉完全没有机会的样子了!

4 评论

  1. 木头大佬。 cocos一直跟着你学。非常崇拜。。。 但是这个框架,看到这儿我已经要放弃了,“太复杂“”太臃肿了“(恕我愚昧),能简单点评下这个框架吗?

    1. 如果觉得Starforce解读很难懂的话,那是正常的,你可以跳过,直接从Demo教程开始看。
      框架作者把Starforce封装地很复杂,除了要理解框架的使用方式以外,还需要了解作者的开发思路,所以有点累。

      这个框架还是很不错的,不过不建议新手学习咯(不知道你是新手还是老手呢),新手直接学习怎么用Unity3D写游戏就可以了,学习框架还为时尚早。

      1. 感谢木头大佬回复, 新手但是还算能看懂,只是没明白这样复杂封装的好处在哪儿。。。。

        1. 如果只是针对Starforce这种级别的项目,这个封装是没有什么好处的。

          但如果是实际开发的项目,这种封装还是有意义的(但也不是说100%就要按它来),就拿ShowEntity来说,如果不封装一下,那么在创建不同实体的时候会有很多看起来差不多的代码段,这样的代码段写多了,开发者自然会觉得不舒服。
          所以,这样的代码段通常都会封装起来,方便维护和修改。

发表评论

电子邮件地址不会被公开。 必填项已用*标注