前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高效使用lua作为业务开发语言的秘诀在这里!

高效使用lua作为业务开发语言的秘诀在这里!

作者头像
腾讯开源
发布2018-09-06 17:54:18
3.5K1
发布2018-09-06 17:54:18
举报

导语

你还在使用c++开发UE4吗?会不会感觉太慢了?会不会感觉编译一次就可以去楼下喝杯咖啡了?会不会感觉总是提心吊胆,搞不好什么时候就crash了?现在不用发愁了,slua出unreal版本了,在unity上广泛流行的slua发布了unreal版本,还是那么强大,还是那么好用,你还等什么,赶快上船吧。

1 为何做unreal版本?

目前unreal提供的开发语言包括c++和蓝图,但这2个开发语言都或多或少存在一定的问题,对于c++来说,最大的问题是c++开发人员越来越少,精通c++开发的同学更少,而且c++本身并不是描述业务的最好语言,稍微不留心就容易崩溃或者内存泄露,这是不能接受的,其次unreal下修改c++编译时间太过漫长,如果还修改了header文件,那每次编译真的可以去喝一杯咖啡了,工作效率不高,还有就是调试,如果你想快点运行,选择dev build,则势必丢失一些调试信息,或者出现错误调用栈,或者某些局部变量看不到信息,或者某些断点失效,如果你选择debug build,则启动速度慢,运行慢,好好的一个i7多核计算机,搞的比乌龟都慢,如果正好赶上项目上线,问题频发,想死的心都有。

如果你选择使用蓝图,我只能说作为程序员你骨骼清奇,这玩意都能用于实际业务开发,跑跑demo,做做prototype还行,一般没有业务用蓝图作为主要开发语言用于产品,它最大的问题是不能merge,无法多人协作开发;稍微修改一些接口,某些slot就要重新链接;稍微大一点的蓝图程序看着都头晕。一般蓝图都是作为配置或者流程描述来用。

有介于此,做一套脚本化的开发语言是必须的。

2 Unreal自身提供lua支持?

对,你没有看错,Unreal早期版本其实内建支持lua,只需要自己开启一个宏WITH_LUA,然后重新编译unreal引擎,就可以开启lua,但这个功能在unreal仅仅是概念演示,而且从某个版本之后也不再维护了,实际使用起来也有很多问题,更重要的是,这个功能需要重新编译UE4,这对于大多数拿着引擎就是开箱即用的开发组,重新编译引擎是不现实的,所以我们需要提供一个扩展的插件,不用重新编译,也能方便使用lua来开发。

有介于此,slua 的 unreal 版本诞生了,当然你会问slua什么鬼?嘿嘿嘿,slua就是在unity下广泛流行的lua开发插件,适用于在unity引擎使用lua作为开发语言开发游戏业务,而作者就是我本人,那理所当然,我有必要做一个unreal版本方便slua的用户可以快速迁移到unreal下,因为我是一个负责任的开源软件作者。

3 slua unreal版本提供什么功能?

这说起来就有点激动了,说了这么多也总算进入正题了。

1)对于蓝图类和蓝图方法的调用 什么是蓝图类和蓝图方法呢?就是所以标记了了UCLASS和UFUNCTION的类和函数,UE4为这些类和函数提供反射能力,通过使用反射,slua可以方便调用这些函数,蓝图自己也使用这些反射能力来支持蓝图调用,所以理论上我们使用这些能力来供lua调用,不会比蓝图自己更慢。

2)支持使用lua function作为蓝图的事件代理

在蓝图里支持代理,例如:

这个OnClicked就是代理,可以绑定一个c++函数,或者绑定一个蓝图slot用于触发事件调用函数,slua支持传入一个lua function作为代理函数,调用进入lua函数。例如:

3)对于非蓝图类和非蓝图方法,支持基于静态代码生成的自动导出 和 基于模板展开的手动添加

在实际项目中,我们有很多代码并非是蓝图类,但也需要在lua中使用,比如最常见的FVector,这个类并不是蓝图类(一般蓝图类都是U开头的类),但我们需要在lua中使用FVector来完成位置、方向的计算,我们就需要把FVector导出到lua中使用,为此slua附带了一个工具,通过这个工具可以自动化的导出我们指定的c++类,并生成对应的静态代码,这个工具是基于libclang,它使用libclang产生的反射信息来完成代码生成,这点上类似Unity版的slua,最终生成的代码如下:

可以看到slua将FVector的成员方法都导出了,整体的代码风格与slua unity版本类似。

除了支持静态代码生成的导出,也支持基于可变参数模板的导出,这需要手动添加简单的导出代码,例如:

slua会基于可变参数模板自动展开代码,产生正确参数解析和函数返回值,生成对应的导出函数,不需要对原始c++类做任何注入式的修改。

4)支持数学运算符重载

正如上面提到的FVector,它需要若干计算功能的函数,如果是突兀的Add,Mul看起来很奇怪,而且本身FVector在c++层面也支持运算符重载,所以slua也将这部分能力导出到了lua里,支持在lua层面的运算符重载,方便代码书写。

5)从蓝图直接调用到lua并返回任意返回值

一般使用lua的情景是从c++代码调用lua,但蓝图提供了热更新的能力,有时候我们希望通过蓝图的热更新能力来启动lua代码,这个时候就需要从蓝图调用lua函数,同时返回lua返回值到蓝图,例如有如下lua函数:

我们可以构造如下蓝图来调用lua

我们可以传入任意数量的参数,任意参数类型,并返回任意个数的返回值。

6)支持out类型的蓝图参数和引用类型的c++参数作为返回值

与c#类似,蓝图也支持out类型的参数用于返回多余的返回值,而c++这里,一般我们使用非const引用来返回多余参数(当然也可能不),slua支持这种使用情况,对于out类型的蓝图函数参数会额外返回,对于非const的函数参数也会额外返回,对于c++这里,slua无法区分函数设计时的语义,只要非const的引用类型,都会额外当做返回值返回,当然你可以选择忽略不使用。

7)通过静态代码生成,导出了UE4所有的enum,并使用int支持enum参数

8)支持扩展方法

类似c#的extension method,slua unreal也支持扩展方法,什么是扩展方法呢?比如一个UUserWidget这个蓝图类,存在如下方法:

它并不是蓝图方法,但存在在蓝图类里,我们可能非常需要这个函数能够导出到lua使用,但我们又不想为此修改引擎代码,添加一个UFUNCTION标签,这时我们可以做一个扩展描述:

这样就为UUserWidget添加2个扩展方法,这2个方法可以在lua侧被调用,可以看到第一个GetWidgetFromName方法直接使用UUserWidget的成员方法,第二个RemoveWidgetFromName方法则是手动实现了一个版本,通过这样描述,我们不需要修改UE4引擎就可以为UUserWidget添加扩展的lua方法,非常方便。

最后我们看一个完整使用demo代码:

目前slua unreal持续开发升级中,更多功能不断推出,如果你正在做unreal游戏?如果你正在考虑unreal下如何热更新?如果你正在考虑unreal下的脚本解决方案?不妨试试slua unreal。

4 使用案例

说了这么多,大家一定会问,你吹的那么牛逼,到底有没有项目用?答案是 slua-unreal 已经集成在潘多拉智能营销解决方案,用于支持腾讯多款游戏业务,通过了DAU千万级的产品测试,上线质量稳定,大家可以放心使用。

5 项目地址

slua-unreal已在Github上开源, 开源地址:

https://github.com/Tencent/sluaunreal

大神力作,欢迎Star,Watch,fork,pr!

作者简介

庞巍伟,腾讯移动客户端技术专家、技术总监,slua作者,14年游戏开发经验,对端游、页游、手游都有丰富开发经验,曾参与《梦幻西游》《天下贰》《神将三国》等游戏项目的全程开发工作,目前负责腾讯IEG潘多拉 智能营销解决方案的技术建设、架构工作。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯开源 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
  • 1 为何做unreal版本?
  • 2 Unreal自身提供lua支持?
  • 3 slua unreal版本提供什么功能?
  • 4 使用案例
  • 5 项目地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档