查看原文
其他

腾讯G6与Epic Games China联合共建Lua脚本方案

腾讯G6 虚幻引擎 2020-08-25

简介


UnLua是虚幻引擎4下的特性丰富且高效的脚本解决方案,由腾讯G6团队与Epic Games China团队共同打造。它的特色在于利用引擎的反射机制按需动态导出,无需大量胶水代码;完备的静态导出功能,用于导出非反射系统的类、函数、枚举;可以覆写(override)所有'BlueprintEvent'、Replication Notify、Animation Notify、Input Event,通过Lua来扩展C++、Blueprint;可以替换线上系统原有Blueprint逻辑。  



基于UnLua的LiveCoding实践  


  • 对于脚本的修改,实时可在手机验证,无需重启游戏,动态增加函数去 override Blueprint 函数。 

  • 对于资源的修改,所有的uasset,无需打包,手机重启游戏便可验证,方便的验证资源在各个平台的表现。 



代码改动在运行时实时生效,UnLua是在虚幻引擎下Livecoding的基石。  




痛点  


  • 面对多变的市场,迭代速度是团队发展的重要挑战。 

  • 代码的编译,资源的Cook,以及最终的打包,导致团队花费大量时间等待出版本,所谓的“版本之夜”也越来越多,越来越长。 

  • 玩家的成熟度已经较高,线上出现的问题需要快速修复。 


所以我们需要轻量级,能够方便热更新的Lua脚本解决方案。  



为什么设计UnLua  


Blueprint是虚幻引擎4设计的重要元素,在资源配置和管理,快速构建原型等方面有着原生的优势。但在完成设计模式,巨量代码管理等工程化业务逻辑方面却并不得心应手,这方面文本化脚本语言有着巨大的优势。  


Lua脚本解决方案最基本的功能就是Lua与宿主的双向访问,当前市面上的方案存在以下一些问题:  

  • 胶水代码静态导出方案,通过UHT自动生成胶水代码(限反射体系内的类、结构等),代码量大增,拖慢编译速度,运行时占用过多内存。 

  • 反射机制动态导出方案,不支持默认参数,调用引擎函数时效率不够理想,返回值处理不够高效,与静态导出方案结合的不够紧密。 

  • 以上两种方案在引擎访问Lua时都需要额外辅助代码,不够自然,不符合熟悉Blueprint程序员的编程习惯。 


为此,我们设计了一套易于扩展引擎、Blueprint,并与之紧密结合的Lua脚本解决方案。  



Unreal Way  


UnLua的设计理念是Coding Like Unreal,我们的动态导出方案提供如下特性:  


直观的访问  



  • 访问UCLASS

UKismetMathLibrary.RandomFloatInRange(0, 100) 
  • 访问USTRUCT

local HitResult = FHitResult() 
  • 访问UFUNCTION

self:Jump() 
  • 访问UPROPERTY

local Controller = self.Controller
  • 访问UENUM(包括自定义的碰撞枚举)

local TraceType = ETraceTypeQuery.Weapon 
  • 绑定Delegagte

self.ExitButton.OnClicked:Add(self, function() UKismetSystemLibrary.ExecuteConsoleCommand(self, "exit") end ) 
  • 协程中执行Latent函数,同步写法完成异步逻辑。

coroutine.resume(coroutine.create(function(Duration) UKismetSystemLibrary.Delay(self, Duration); print("done!") end), 5.0)
  • 提供了可选的'UE4'名字空间

local HitResult = UE4.FHitResult()


自然的扩展  



无需任何辅助代码  


  • 可以在Lua中覆写所有'BlueprintEvent' 

◦ 所有用BlueprintImplementableEvent标记的UFUNCTION 

◦ 所有用BlueprintNativeEvent标记的UFUNCTION 

◦ 定义在Blueprint里的所有Event/Function 

  • 可以在Lua中覆写Replication Notify

  • 可以在Lua中覆写Animation Notify 

  • 可以在Lua中覆写Input Event 



静态导出  


除了基于反射系统的动态导出,UnLua还提供了完备的静态导出功能,用于导出非反射体系的类、函数、枚举,并且与动态导出的反射系统数据紧密结合,支持混用。  



效率  


  • 高度优化的UFUNCTION调用,包括优化的参数传递、优化的'ProcessEvent'、优化的返回值处理。性能优于Blueprint。

  • 高度优化的基础容器访问。Lua中可直接创建TArray、TSet、TMap,支持类型信息,且其内存布局与C++侧一致,无需在Lua Table和容器间转换,极大提升效率。 

local A = TArray(AActor)
  • 手动导出FVector, FVector2D, FVector4, FQuat, FRotator, FTransform等常用数学库,支持优化的调用方式,效率更高。 



更多特性  


  • 通过UHT自动生成1000行以内代码,对动态导出UFUNCTION的默认参数提供支持。 

  • 支持编辑器内的Sever/Clients模拟。 

  • 内嵌编辑器的Lua Debugger,支持单点调试,查看变量,查看Lua及C++堆栈。 

  • 提供了和Blueprint一样的死循环监测,当Lua脚本发生死循环,会停止当前调用并打印堆栈。 

  • 提供了编辑器扩展,根据Blueprint类型自动生成Lua模板代码,包含了一些可能需要实现的函数,类似新建Blueprint中提供的默认函数、Unity新建Class中提供的默认函数。 

  • 覆写的Lua函数支持引擎内置的Profiling工具。 



展望  


2017年,腾讯正式开始用虚幻引擎4开发移动游戏,同时双方进行了深度技术优化的合作探索,取得了很好的效果。 2018年,双方开始针对“迭代效率”的痛点,一起合作探索了虚幻引擎的LiveCoding实践,同时还将联合开发虚幻引擎4性能分析工具。 未来,针对中国开发者,双方还会进行更多特性合作改造,提升虚幻引擎4的开发效率和质量。  


以下特性正在建设,可以期待  


  • 更高效的 Cook on the fly(基于USB) 

  • 增强的UMG,支持3D,2D混排 

  • 更好的Lua Debugger 


G6 Team : G6是腾讯GCloud体系下,致力于游戏框架搭建,提供游戏云服务的部门。




III  活动预告  III


9月15日:Unreal Circle 上海站 

虚幻引擎巡回技术分享沙龙



III  近期焦点  III





    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存