cryengine3中lua脚本模块集成笔记

来源:互联网 发布:python tkinter opengl 编辑:程序博客网 时间:2024/05/16 06:22
      公司上个仿真项目使用了cryengine3来制作,所以有机会接触和分析世界顶尖的引擎。作为一个通用引擎,那么必须具备很好的扩展性,让用户能够自定义开发,其中脚本是不可缺少的一个模块,与unreal engine 3的专用脚本不同,ce3使用了lua脚本,因wow而出名。由于lua是一个独立的脚本语言,所以可以集成任何引擎,而分析ce3可以学习顶尖引擎是如何设计和集成脚本的。
      首先谈下自己对脚本模块的看法,脚本的好处是即时修改,不用重新编译并运行exe程序,基于这个好处,可以把可能会经常修改调整的逻辑用脚本来实现,而引擎只负责基本不变的逻辑。但变与不变具有相对性,对专用引擎来说,因为需要定制很多功能,所以经常 变的主要是这些功能的配置等逻辑,而对通用引擎来说,理论上用户可以自定义开发各种各样的游戏,所以整个游戏逻辑都属于会变的,应该可以由脚本来实现,当然完全独立出来是不现实的,因为有些逻辑跟引擎结合很紧或脚本实现效率太低。
      现在回到ce3,ce3确实尽量把很多游戏逻辑独立出来,比较深入用过ce3的编辑器sandbox的人应该有所体会,sandbox里面有很多entity对象,这些对象都有脚本文件,实际上这些对象都是由自己的脚本文件创建出来的,用户可以通过创建脚本来创建自己的entity和entity的游戏逻辑,下面分析下ce3里面entity的lua脚本集成做法,只记录下实现思想,不涉及具体代码。
1、用lua表现一个entity对象
     在c++中要表现一个对象最常用的就是类(类包含数据和函数),lua中没有类,但使用的技术可以变相实现相同的效果,lua通过table、 meta table、__index、__newindex来实现c++类中的基类和派生类,ce3中entity对象都是以table来定义的,对象的属性和函数都是table中的数据。
2、引擎和脚本的交互
     一个lua对象定义好后,那么需要和引擎就需要进行交互,如:创建一个实例、修改实例属性、调用实例的函数等。
     ce3在引擎脚本模块初始化时会扫描entity的资源,把每个entity对象(table)加载到lua中,然后c++内保存的lua中的引用,这个entity对象或者说table对象是被实例所共享。

     当加载关卡或sandbox编辑时一个entity对象可能会产生多个实例,每个实例的属性可以不同,游戏过程中可以调用实例的函数或事件进行交互。这一过程中引擎内部的实际操作是这样的:实例创建的实际操作是创建了两个lua内的table,一个是实例,一个是属性,然后将上面提到的共享的对象中的属性表(以字符串"properties"命名)复制到实例的属性,这些值对于编辑时新加的实例是默认值,关卡加载时这些值则会被编辑时编辑后的值覆盖,最后属性(表)会放到实例(表)中,然后共享的对象表作为实例的__index,这样实例就"继承了"entity的函数。

    当引擎调用entity的函数时,将实例(一个lua table)作为第一个参数传给实例的函数,这样函数内访问的值就是实例的值而不是共享对象的值。

    由于引擎对脚本的定义是一无所知的,所以所有属性和函数都是用字符串作为关键字来访问的,也预设了一些关键字,如上面提到的属性表名为"properties"还有一些函数名,函数调用参数个数在引擎内部也是预先定义好多个参数的模板。除了一些预设的函数,比如实例的初始化,引擎一般不会调用实例的函数(也不知道entity有那些函数),这些函数通常由用户定义的逻辑来调用,如flowgraph、ai、trackview等。

    笔记比较凌乱,主要用于记录自己理解一些思想,要实现完整的脚本模块还有非常多的细节需要考虑和完善。

    

0 0
原创粉丝点击