首页 > 其他分享 >[UnrealCircle]腾讯 罗谦 | UnLua-UE4下的Lua脚本插件

[UnrealCircle]腾讯 罗谦 | UnLua-UE4下的Lua脚本插件

时间:2024-08-04 18:38:33浏览次数:12  
标签:罗谦 插件 函数 Thunk 覆写 UFunction Lua UnLua

传送门:[UnrealCircle]腾讯 罗谦 | UnLua-UE4下的Lua脚本插件_哔哩哔哩_bilibili

参考PPT:UnrealCircle921北京PPT_免费高速下载|百度网盘-分享无限制


一. UnLua 基础

1.1 概念

  • UnLua 是一个脚本插件
  • UnLua 不是蓝图的替代,而是一种补充
    • 没有 Asset 预览
    • 不支持 nativization
    • 无法保持内容的引用
  • UnLua 为使用 Lua 编写游戏逻辑提供了支持

 

 

1.2 主要特性

  • 无需胶水代码访问 UCLASS、UPROPETY、UFUNCTON、USTRUCT、UENUM
  • 无辅助代码覆写(Overide)BlueprintEvent
  • 无辅助代码覆写(Overmide) AnimNottfy
  • 无辅助代码覆写(Overide) RepNottfy
  • 无辅助代码覆写(Overide) Input Event
  • 简单完备的静态导出方案
  • 高度优化的 UFUNCTION 调用
  • 高度优化的容器(TAray、TSet、TMap)访问
  • 高度优化的结构体访问
  • 支持 UFUNCTON(带'BlueprintCallable' 或 'Exec' 标签)默认参数
  • 支持自定义的碰撞检测相关枚举
  • 支持编辑器内 Server/Cllent 模拟
  • 支持 Lua 协程中执行 Lateni 函数,同步写法完成异步逻辑
  • 支持根据 Blueprint 类型自动生成 Lua 模板代码

 

 

二. 使用原理

2.1 引擎和 Lua 绑定

  1. 静态绑定
    • 仅一个 Interface 和一个纯虚函数
    • 同时支持蓝图类和 C++ 类

 

  1. 动态绑定
    1. 动态创建的 Object
    2. 动态生成的 Actor

 

 

2.2 Lua 访问引擎

 

  • 无巨量的胶水代码
  • 支持反射体系内的所有数据
  • 手动导出一些最基础的函数
    • UObject.Load、UObject.GetName、UObject.GetClass...
    • UClass.Load、UClass.lsChildOf...
    • UWord.SpawnActor...
  • 手动导出数学库
    • FVector、FVector2D、FVector4、FQuat、FRotator、FTransform...

 

 

  • 访问 UClass

 

  • 访问 UStruct:

 

  • 访问 UEnum

 

  • 访问自定义的碰撞检测相关的 UEnum

 

  • 访问 UProperty

 

  • 访问 Delegate/Multi-cast Delegate/Sparse Delegate

 

  • 访问 UFunction

 

  • UFunction 非常量引用参数处理(原子类型)

 

  • UFunction 非常量引用参数处理(非原子类型)
  • 第一种写法在性能上远远高于第二种

 

  • UFunction 返回值参数处理(原子类型)

 

  • UFunction 返回值参数处理(非原子类型)
  • 在有性能要求的场合,建议使用下面第二、三种写法

 

  • 访问 Latent Function
  • 支持在 Lua 的协程中做 Latent Function 的调用(用同步的写法完成异步的逻辑)

 

  • 访问基础容器(TArray、TMap、TSet)
  • Lua 语言本身不支持模板,UnLua 进行特殊处理后把 C++ 里面的类型信息用 Lua 中的参数代替
    • TArray(0)对应 C++代码中实例 TArray<int 32>
    • TArray(FVector)对应 C++代码中实例 TArray<FVector>
  • 在 Lua 中创建的这些容器实例,在 memory layout 内存的布局上,是和引擎一致的,没比要再进行容器到 Lua Table 间的转换

 

  • 静态导出反射体系外的数据
  • 均为程序员手动操作控制,如果修改了类(如:修改了函数签名,函数原型发生了变化)又正好要导出,则需要修改两处

 

 

2.3 引擎访问 Lua

  • 使用 UnLua 插件
  • UnLua 插件区别于其他同类 Lua 插件的最大地方:可以覆写

 

  • Override覆写所有 BlueprintEvent:
    • 用 BlueprintImplementableEvent 标记的 UFunction
    • 用 BlueprintNativeEvent 标记的 UFunction
    • 所有蓝图中定义的 Events/Functions
  • 以上三种类型的 UFunction,都可以直接在 Lua 中写同名函数来覆写,而没有任何辅助代码

 

  1. 覆写 BlueprintEvent:
    • 覆写不带返回值的 BlueprintEvent

 

    • 覆写带返回值的 BlueprintEvent

 

  1. 覆写 AnimNotify

 

  1. 覆写 RepNotify

 

  1. 覆写 Input Events

 

 

三. 重要特性

3.1 覆写的实现

  1. Thunk Function 函数
    • 在 4.23 引擎版本下的 Thunk Function 函数:FNativeFuncPtr Func

 

    • 在 4.19 引擎版本前,Thunk Function 函数指针的原型历史:

 

  1. Thunk 函数的调用
    • UFunction 的执行大概率会走到ProcessEvent函数,并最终通过 Thunk Function 的调用实现(如果将 Thunk Function 指针替换为自定义的可调用 Lua 的函数,则可以实现覆写)

 

  1. Thunk 函数替换
    • 一个 public 函数

 

  1. Thunk 函数替换不适合所有场景
    • 对于在蓝图中定义且在蓝图中被调用的函数或 Events,则走CallFunction函数(不会走到ProcessEvent函数),不通过 Thunk 函数的调用,引擎为所有非 native UFunction 定义的默认的 Thunk Function,被写死了,不管换成什么都没用

 

    • 解决此问题的一些“野路子”:
    • 由于ProcessInternal函数是脚本语言,可以对编译好的字节码进行解释执行,在覆写时,动态插入到字节码序列中
    • 自定义新的 Opcode 注册

 

    • Opcode 注入(引擎处理时,会检测 return、nothing)

 

  1. 返回值处理
    • 非 const 引用参数、return 返回值

 

 

3.2 优化的思路

  1. 结构体访问优化
    • 结构体创建

 

    • 直观实现(伪代码)
    • 在内存的操作上:两个 malloc、一个构造函数

 

    • UnLua 实现(伪代码)
    • 在内存的操作上:一个 malloc、一个构造函数

 

    • 创建时节省一次内存分配,GC时节省一次内存释放
    • Userdata 内存布局:为了满足引擎对一些数据结构的结构体边界对齐要求,使用 Padding 填充,缓存友好(不需要二级指针之类的常规处理),但 Padding 会造成一定的内存浪费,影响不大

 

 

  1. UFunction 调用优化
    • 持久化参数缓存
    • 第一次调用时就被分配好了,最后才被释放掉,(避免频繁的 malloc 和 free)

 

    • 为 Native Local 函数返回值参数,预分配缓存(Local 对应 RPC 函数)

 

    • 为 Native Local 函数提供快速调用路径

 

 

  1. 传参优化
    • UFunction 带常量引用参数

 

    • 直观实现(伪代码)

 

    • UnLua实现(伪代码)
    • Memcpy 浅拷贝,经过大量实践有正确性的保证,且对于复杂数据结构(如:含有大量元素的容器),浅拷贝的性能优势巨大

 

 

  1. 非常量引用参数优化
    • UFunction 带非常量引用参数

 

    • 和 C++ 类似的 Lua 调用方式

 

    • 两次浅拷贝(传参和值返回各一次)

 

 

  1. 返回值参数优化
    • UFunction返回非原子类型

 

    • 直观实现:新创建 Userdata 并将其压入 Lua 栈顶
    • UnLua 实现
    • 先创建 Userdata 并将其作为参数传入函数
    • 利用了传参优化
    • 多次调用(例如循环)情况下,避免了大量的 Userdata 创建和 GC,性能优势明显

 

 

3.3 智能语法提示

  • UnLua 插件中,内置了智能语法提示功能

 

  1. 符号信息(反射体系内)
    • 导出单独的 UnLuaIntelliSense 模块
    • 和 UHT 一同工作,在编译时就生成了所有反射体系内数据的符号信息,为智能语法提示信息提供基础,
    • 符号信息位于ProjectDir/Plugins/UnLua/Intermediate/IntelliSense

 

  1. 符号信息(反射体系外)
    • UnLuaIntelliSense Commandlet
    • 符号信息位于ProjectDir/Plugins/UnLua/Intermediate/IntelliSense/StaticallyExports

 

  1. IDE 中的智能语法提示 API(Lua 语法提示插件:EmmyLua)

 

 

3.4 调试

  1. 调试工具:Debug Any Where

 

标签:罗谦,插件,函数,Thunk,覆写,UFunction,Lua,UnLua
From: https://www.cnblogs.com/ZWJ-zwj/p/18342070

相关文章

  • Typecho页面浏览次数统计插件已修正适配Typecho 1.2
    沧海桑田,时隔多年Typecho终于迎来了重大更新(竟然在有生之年更新了(狗头保命))。Typecho刚发布的时候还是PHP5流行的时代,本身升级了更高语言版本,带来了更好的程序执行效率,提高了编程效率,但升级后存在发现“页面浏览次数统计插件”插件不能使用了。问题回顾我一直用的是作者(H......
  • 浏览器插件监听元素变动-用于直播自动回复
    直播获取评论区的原理MutationObserver是一个强大的浏览器API,它可以监听DOM的变化,包括元素的添加、删除、属性的更改等。开发需求可联系vx:llike620步骤:创建一个MutationObserver实例,并提供一个回调函数。使用observe方法指定要监控的DOM节点和具体的变动类型。在回调函数......
  • ComfyUI插件:ComfyUI layer style 节点(四)
    前言:学习ComfyUI是一场持久战,而ComfyUIlayerstyle是一组专为图片设计制作且集成了Photoshop功能的强大节点。该节点几乎将PhotoShop的全部功能迁移到ComfyUI,诸如提供仿照AdobePhotoshop的图层样式、提供调整颜色功能(亮度、饱和度、对比度等)、提供Mask辅助工具、提供图层合成......
  • 直播自动回复浏览器插件开发-抖音直播自动回复插件-抖音小店飞鸽客服自动回复插件(简单
    抖音直播自动回复插件抖音小店飞鸽客服自动回复插件演示网站:https://gofly.sopans.com/douyin.html开发浏览器插件是一个相对复杂的过程,涉及到前端开发、浏览器API的使用以及插件的架构设计。以下是开发浏览器插件的一般步骤:了解浏览器插件基础:学习浏览器插件的基本概念,包......
  • 【Obsidian插件】(2)Zotero Integration插件设置界面介绍
    ZoteroIntegration插件可以将Zotero(文献管理软件)与Obsidian(笔记软件)整合起来,通过引用文献或导入注释等操作,以提高文献阅读和笔记记录的效率。本文主要介绍该插件的设置界面:目录1一般设置(GeneralSettings)1.1PDFUtility1.2自定义PDFUtility路径1.3数据库1.4笔......
  • 推荐 7 个 VS Code 插件,让 Coding 更加丝滑
    VisualStudioCode(VSCode)凭借其强大的功能和可扩展性,已经成为许多开发者的首选代码编辑器。为了进一步提升编程体验,VSCode提供了丰富的插件生态系统,这些插件能够极大地提升开发效率和代码质量。本文将推荐7个必备的VSCode插件,让你的coding体验更加丝滑。1. Python......
  • Lua 脚本编程基础
    引言Lua是一种轻量级的脚本语言,用标准C编写,设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。由于其简洁和高效,Lua在游戏开发、嵌入式系统、网络编程等领域得到了广泛应用。Lua语言特点轻量级:Lua的解释器可以轻松嵌入到任何应用程序中。简洁:Lua......
  • 最火的十大 Edge插件:安装指南、功能介绍及使用技巧
    最火的十大MicrosoftEdge插件:安装指南、功能介绍及使用技巧随着网络浏览需求的不断增加,浏览器插件变得越来越重要。MicrosoftEdge通过其丰富的插件生态系统,满足用户的多样化需求。本文将介绍十款在中国用户中最受欢迎的Edge插件,包括如何安装、使用及其主要功能和作用。这些......
  • ComfyUI插件:ComfyUI layer style 节点(三)
    前言:学习ComfyUI是一场持久战,而ComfyUIlayerstyle是一组专为图片设计制作且集成了Photoshop功能的强大节点。该节点几乎将PhotoShop的全部功能迁移到ComfyUI,诸如提供仿照AdobePhotoshop的图层样式、提供调整颜色功能(亮度、饱和度、对比度等)、提供Mask辅助工具、提供图层合成......
  • shell获取敏感词接口json数据更新时重启nginx+lua环境、一个逐步删除服务器上文件夹的
    一、shell获取敏感词接口json数据如有更新重启nginx+lua环境    因为工作需要,需要写一个shell脚本获取对应接口的数据(其它管理后台控制的敏感词库)。因为当前平台是nginx+lua脚本,重装加载敏感词需要重启nginx.实现起来也很简单,第一点,需要对获取的json数据进行分析,shell......