xLua教程

合集下载

Unity热更新XLua

Unity热更新XLua

Unity热更新XLua 什么是冷更新开发者将测试好的代码,发布到应⽤商店的审核平台,平台⽅会进⾏稳定性及性能测试。

测试成功后,⽤户即可在AppStore看到应⽤的更新信息,⽤户点击应⽤更新后,需要先关闭应⽤,再进⾏更新。

什么是热更新⼴义:⽆需关闭应⽤,不停机状态下修复漏洞,更新资源等,重点是更新逻辑代码。

狭义定义( iOS热更新):⽆需将代码重新打包提交⾄AppStore,即可更新客户端的执⾏代码,即不⽤下载app⽽⾃动更新程序。

现状:苹果禁⽌了C#的部分反射操作,禁⽌JIT(即时编译,程序运⾏时创建并运⾏新代码),不允许逻辑热更新,只允许使⽤AssetBundle进⾏资源热更新。

注意:2017年,苹果更新了热更新政策说明,上线后的项⽬,⼀旦发现使⽤热更新,⼀样会以下架处理为何要热更新缩短⽤户获取新版应⽤的客户端的流程,改善⽤户体验具体到iOS平台的应⽤上,有以下⼏个原因AppStore的审核周期难控制⼿机应⽤更新频繁对于⼤型应⽤,更新成本太⼤终极⽬标不重新下载、不停机状态下完全变换⼀个应⽤的内容每个平台如何做热更新Android,PC(C#)将执⾏代码预编译为AssemblyDLL将代码作为TextAsset打包进AssetBundle运⾏时调⽤AssemblyDLL代码更新相应的AssetBundle即可实现热更新iOS(Lua)苹果官⽅禁⽌iOS下的程序热更新;JIT在iOS下⽆效热更新⽅案:Unity + Lua插件常见的Unity热更新插件sLua:最快的Lua插件toLua:由uLua发展⽽来的,第三代Lua热更新⽅案xLua:特性最先进的Lua插件ILRuntime:纯C#实现的热更新插件xLua的安装将Assets⽬录下所有⽂件拷贝到项⽬中xLua解析器的获得DoString函数执⾏Lua代码Lua代码调⽤C#代码C#加载Lua⽂件根据加载提⽰,发现可以将Lua⽂件放在StreamingAssets⽬录下StreamingAssets被抛弃,所以移动到Resources下(以txt为结尾)⾃定义加载器LuaEnv.AddLoader()接触⼀个新的Lua项⽬时,先要弄懂Lua的加载器规则,只有这样,才能弄懂项⽬的Lua执⾏流程 xLua的单例运⾏环境xLua解析器创建销毁xLua加载器编写xLua中Lua调⽤C#代码为什么? C#实现的系统,因为Lua可以调⽤,所以完全可以换成Lua实现,因为Lua可 以即时更改,即时运⾏,所以游戏的代码逻辑就可以随时修改。

PhpStorm2020+phpstudyV8+XDebug的教程详解

PhpStorm2020+phpstudyV8+XDebug的教程详解

PhpStorm2020+phpstudyV8+XDebug的教程详解WNMP(Windows+Nginx+Mysql+Php)环境安装操作:1、安装phpStudy1.1、下载phpStudy下载地址:/解压后运⾏exe进⾏安装,我的安装⽬录是:D:\phpstudy_pro1.2、配置环境:在桌⾯启动⼩⽪进⾏配置,我的配置如下:⾸页⾯板:启动"WNMP"⽹站⾯板:PHP版本环境⾯板:数据库、PHP运⾏环境2、安装PhpStorm20202.1、下载phpStudy我使⽤的是缺省⽬录进⾏安装,如何激活在这就不详细说了。

2.1、配置PHP版本信息我们点击“File->Settings”菜单进⾏PHP版本配置,使⽤和phpstudy对应的版本PHP7.3.4。

注意:Interpreter默认是没有的,我们需要点击右边的按钮进⾏配置。

3、新建测试⼯程3.1、使⽤PhpStorm新建⼯程"HelloPHP"第⼀步:打开PhpStorm软件,点击创建新项⽬,在输⼊框填写带项⽬存放地址的项⽬名称,完成后点击创建。

3.2、配置⼯程的本地服务我们点击“⼯具/部署/配置”菜单进⾏本地服务配置点击确定后进⾏具体配置:Connection⾯板:配置部署⽬录Mappings⾯板:配置相对⽬录和访问地址配置完之后点击“确定”。

3.3、配置运⾏环境我们点击“运⾏/编辑配置”菜单进⾏运⾏环境配置选择⼯程,单击右键->New->PHP File输⼊⽂件的名称,点击确定增加PHP⽂件在新建的⽂件⾥输⼊代码:<?phpecho "Hello PHP!"; // 在页⾯上输出“Hello PHP!”phpinfo(); // 调⽤PHP内置的函数显⽰PHP的基本信息3.5、部署⼯程在菜单中选择Tools->Deployment->Upload to localhost上传⼯程。

腾讯开源手游热更新方案,Unity3D下的Lua编程

腾讯开源手游热更新方案,Unity3D下的Lua编程

腾讯开源⼿游热更新⽅案,Unity3D下的Lua编程作者|车雄⽣编辑|⽊环腾讯最近在开源⽅⾯的动作不断:先是微信跨平台基础组件Mars宣布开源,腾讯⼿游⼜于近期开源了Unity3D下Lua编程解决⽅案——xLua。

xLua,何⽅神圣?有哪些技术细节可以说道说道?写在前⾯xLua是Unity3D下Lua编程解决⽅案,⾃2016年初推⼴以来,已经应⽤于⼗多款腾讯⾃研游戏,因其良好性能、易⽤性、扩展性⽽⼴受好评。

现在腾讯已经将xLua开源到GitHub。

2016年12⽉末,xLua刚刚实现新的突破:全平台⽀持⽤Lua修复C#代码bug。

⽬前Unity下的Lua热更新⽅案⼤多都是要求要热更新的部分⼀开始就要⽤Lua语⾔实现,不⾜之处在于:1. 接⼊成本⾼,有的项⽬已经⽤C#写完了,这时要接⼊需要把需要热更的地⽅⽤Lua重新实现;2. 即使⼀开始就接⼊了,也存在同时⽤两种语⾔开发难度较⼤的问题;3. Lua性能不如C#;xLua热补丁技术⽀持在运⾏时把⼀个C#实现(函数,操作符,属性,事件,或者整个类)替换成Lua实现,意味着你可以:1. 平时⽤C#开发;2. 运⾏也是C#,性能秒杀Lua;3. 有bug的地⽅下发个Lua脚本fix了,下次整体更新时可以把Lua的实现换回正确的C#实现,更新时甚⾄可以做到不重启游戏;这个新特性iOS,Android,Windows,Mac都测试通过了,⽬前在做⼀些易⽤性优化。

那么,腾讯开源的xLua究竟是怎样的技术?它是为何如此设计的?更令⼈关⼼的是,xLua的性能如何?带着这些问题,InfoQ对其作者进⾏了采访并将内容整理成⽂。

技术背景腾讯⾃研⼿游,就我了解的项⽬来说,⼤多数游戏引擎都是Unity3D,少数⽤coco2d。

xLua这个插件具体⽤到了哪些游戏中?虽说xLua是2015年3⽉就完成了第⼀个版本,但由于当时项⽬组热更的意识并没有很普遍,需求不是很强烈,xLua的开发资源都调到更紧急的项⽬了。

XLua增加删除第三方lua库

XLua增加删除第三方lua库

What&WhyXLua目前内置的扩展库:1、针对luajit的64位整数支持;2、函数调用耗时以及内存泄漏定位工具;3、用于支持ZeroBraneStudio的luasocket库;4、tdr 4 lua;随着使用项目的增加以及项目使用的深入程度,仅有这几个扩展已经没法满足项目组了,而由于各个项目对扩展差异化比较大,以及手机平台对安装包大小的敏感,XLua是无法通过预集成去满足这些需求,这也是这篇教程的由来。

这篇教程,将以lua-rapidjson为例,一步步的讲述怎么往xLua添加c/c++扩展,当然,会添加了,自然删除也就会了,项目组可以自行删除不需要用到的预集成扩展。

How分三步1、修改build文件、工程设置,把要集成的扩展编译到XLua Plugin里头;2、调用xLua的C# API,使得扩展可以被按需(在lua代码里头require的时候)加载;3、可选,如果你的扩展里头需要用到64位整数,你可以通过XLua的64位扩展库来实现和C#的配合。

一、添加扩展&编译准备工作把xLua的C源码包解压到你Unity工程的Assets同级目录下。

下载lua-rapidjson代码,按你的习惯放置。

本教程是把rapidjson头文件放到$UnityProj\build\lua-rapidjson\include目录下,而扩展的源码rapidjson.cpp放到$UnityProj\build\lua-rapidjson\source目录下(注:$UnityProj指的是你工程的目录)在CMakeLists.txt加入扩展xLua的各平台Plugins编译使用cmake编译,好处是所有平台的编译都写在一个makefile,大部分编译处理逻辑是跨平台的。

xLua配套的CMakeLists.txt为第三方扩展提供了扩展点(都是list):THIRDPART_INC:第三方扩展的头文件搜索路径。

xlua framework 基础用法

xlua framework 基础用法

xlua framework 基础用法xlua framework 是一种面向游戏开发的 Lua 扩展框架,它提供了一些额外的功能和优化,以提高 Lua 在游戏开发中的性能和灵活性。

基本用法如下所示:1. 导入 xlua 框架:```luarequire("xlua")```2. 定义一个类:```lualocal MyClass = {}MyClass.__index = MyClassfunction MyClass.new()local self = setmetatable({}, MyClass)return selfendfunction MyClass:MyMethod()print("Hello from MyClass!")end```3. 创建对象并调用方法:```lualocal myObject = MyClass.new()myObject:MyMethod()```4. 继承和重写方法:```lualocal DerivedClass = {}setmetatable(DerivedClass, { __index = MyClass }) DerivedClass.__index = DerivedClassfunction DerivedClass.new()local self = setmetatable({}, DerivedClass)return selfendfunction DerivedClass:MyMethod()print("Hello from DerivedClass!")end```5. 调用基类方法:```lualocal derivedObject = DerivedClass.new()derivedObject:MyMethod() -- 输出 "Hello from DerivedClass!" getmetatable(derivedObject).__index.MyMethod(derivedObject) -- 输出 "Hello from MyClass!"```这仅仅是 xlua framework 的基础用法,该框架还提供了很多其他的功能和工具,如自动绑定 C# 类、导出 Unity3D 引擎的接口等,你可以根据具体需求来进一步学习和使用。

Unity使用xLua遇到的坑

Unity使用xLua遇到的坑

Unity使⽤xLua遇到的坑在我们使⽤xLua作为Unity中lua集成的解决⽅案时,遇到了⼀个问题,就是当我们使⽤在lua中把UI中的某个控件绑定相应的事件(如按钮的onClick事件),xLua绑定这个事件是⽤委托实现的,具体代码可以查看xLua的代码。

⽽在程序退出的时候xLua会检查对应的委托有没有被正确的释放掉,如果没有释放掉的话就会抛出异常。

代码如表所⽰:1public virtual void Dispose(bool dispose)2 {3#if THREAD_SAFE || HOTFIX_ENABLE4lock (luaEnvLock)5 {6#endif7if (disposed) return;8 Tick();910if (!translator.AllDelegateBridgeReleased())11 {12throw new InvalidOperationException("try to dispose a LuaEnv with C# callback!");13 }1415 LuaAPI.lua_close(L);1617 ObjectTranslatorPool.Instance.Remove(L);18 translator = null;1920 rawL = IntPtr.Zero;2122 disposed = true;23#if THREAD_SAFE || HOTFIX_ENABLE24 }25#endif26 }这说明我们并没有把对应的委托给释放掉。

所以我们需要确保在程序退出之前所有的委托要正确地释放掉。

⽅案⼤体如下,每⼀个UI都对应⼀个实例,这样在绑定控件的时候创建⼀个匿名函数,这个函数⽤于控件把这个控件绑定的事件清除掉,同时把这个匿名函数放到⼀个数组⾥⾯去,在这个UI销毁的时候调⽤⼀个函数(⽐如我们叫做Destroy),这个函数的作⽤就是负责⼀些清理⼯作,其中就包括遍历前⾯提到的匿名函数的数组并挨个调⽤。

UnityVSCodeXLua断点调试

UnityVSCodeXLua断点调试

UnityVSCodeXLua断点调试去官网下个相对较新的版本,我这里是使用的2023.2.6f1,证书选择个人版。

IDE安装个人习惯使用VSCode,去官网下个新版就行。

为了保证能对C#代码进行断点调试,我们还需要给IDE装上这个C#和DebuggerForUnity的插件。

编写C#代码并断点调试新建一个HelloWorld.csCtrl+Shift+P呼出面板按F5进入调试模式,选择当前正在运行的Unity程序再回到Unity工程将HelloWorld.cs挂载到当前场景内,点击运行代码热更方案我选择的是腾讯的XLua,虽然没怎么深入了解过,但市面上已经有很多商业游戏对其进行过了验证,要满足我们的需求那自然是绰绰有余。

1.需要将Assets文件夹内的东西拷进Unity工程目录下的Assets文件夹内。

(当然如果你有目录洁癖也可以删掉XLua文件夹下的Doc、Examples、Tutorial)2.用c#执行一个Lua脚本。

新建一个c#脚本,挂载到当前Unity场景内,脚本内容如下:using XLua; using System.IO; void Start( { // 启动lua管理器 LuaEnv _l uaEnv = new LuaEnv(; // 重写lua内的require函数回调,方便自定义载入路径 _luaEnv.AddLoader(CustomLoader); // 启动一个脚本载体 LuaTable _scriptEnv = _luaEnv.NewTable(; // 为该脚本添加XLua提供的全局变量及函数 LuaTable meta = _luaEnv.NewTable(; meta.Set("__index", _luaEnv.Globa l); _scriptEnv.SetMetaTable(meta); meta.Dispose(; _scriptEnv.Set("self", this); // 执行该脚本 var _luaScript = LoadLuaFile("HelloWorld"); _luaE nv.DoString(_luaScript, "HelloWorld", _scriptEnv); // 取到Lua脚本内的指定名称函数并运行 Action _luaFunction; _scriptEnv.Get("MyFunction", out _luaFunction); _luaFunction(; // 最后当你不再需要的时候,记得使用.Dispose(销毁脚本载体及管理器 }/// <summary> /// 自定义载入回调 /// </summary> /// <param name="f ilepath"></param> /// <returns></returns> byte[] CustomLoader(ref string fil epath) { filepath = filepath.Replace(".", "/"); return LoadLuaFile(filepat h); }print("Hello World") function MyFunction( print("This is MyFunction") end最后回到Unity运行场景,正常情况下这时控制台就会打印出你的"Hello World"和"This is MyFunction"了。

xlua 热更异步async方法

xlua 热更异步async方法

xlua 热更异步async方法在使用xlua进行热更新时,异步async方法可以帮助我们在热更新过程中处理异步操作,提高程序的并发性能和响应速度。

在xlua中,我们可以使用C#的async和await关键字来实现异步操作。

下面我将从多个角度来介绍xlua中热更异步async方法的相关内容。

首先,xlua是一个针对Unity3D引擎的Lua绑定库,它允许我们使用Lua语言来编写Unity3D游戏的逻辑部分,同时也支持在Lua中调用C#代码。

在xlua中,我们可以通过异步async方法来实现热更新过程中的异步操作,比如网络请求、文件读写等。

在xlua中使用异步async方法,我们可以在C#中定义一个返回Task或Task<T>类型的异步方法,然后在Lua中通过xlua提供的语法来调用这些异步方法。

在C#中,我们可以使用async关键字来定义异步方法,使用await关键字来等待异步操作的完成。

在Lua中,我们可以通过xlua.async来调用C#中的异步方法,并使用lua表达式来处理异步操作的结果。

另外,在热更新过程中,我们可能会遇到一些需要异步处理的情况,比如下载资源、解压文件等。

使用异步async方法可以帮助我们在热更新过程中更加灵活地处理这些异步操作,提高程序的并发性能和用户体验。

总之,xlua中的热更异步async方法可以帮助我们在热更新过程中处理异步操作,提高程序的并发性能和响应速度。

通过使用C#的async和await关键字,以及xlua提供的语法,我们可以更加灵活地处理热更新过程中的异步操作,从而提升游戏的性能和用户体验。

希望这些信息能够对你有所帮助。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

教程
文件加载
一、执行字符串
最基本是直接用执行一个字符串,当然,字符串得符合语法
比如:("(' ')")
完整代码见\\\目录
但这种方式并不建议,更建议下面介绍这种方法。

二、加载文件
用的函数即可
比如:(" ''")
完整代码见\\\目录
实际上是调一个个的去加载,有一个成功就不再往下尝试,全失败则报文件找不到。

目前除了原生的外,还添加了从加载的,需要注意的是因为只支持有限的后缀,放下的文件得加上后缀(见附带的例子)。

建议的加载脚本方式是:整个程序就一个(" ''"),然后在加载其它脚本(类似脚本的命令行执行:)。

有童鞋会问:要是我的文件是下载回来的,或者某个自定义的文件格式里头解压出来,或者需要解密等等,怎么办?问得好,的自定义可以满足这些需求。

三、自定义
在加自定义是很简单的,只涉及到一个接口:
[] ( );
( )
通过可以注册个回调,该回调参数是字符串,代码里头调用时,参数将会透传给回调,回调中就可以根据这个参数去加载指定文件,如果需要支持调试,需要把修改为真实路径传出。

该回调返回值是一个数组,如果为空表示该找不到,否则则为文件的内容。

有了这个就简单了,用的?没问题。

写个调用的接口读文件内容即可。

文件已经加密?没问题,自己写读取文件解密后返回即可。

完整示例见\\\
访问
这里指的是主动发起对数据结构的访问。

本章涉及到的例子都可以在\\下找到。

一、获取一个全局基本数据类型
访问就可以了,上面有个模版方法,可指定返回的类型。

<>("")
<>("")
<>("")
二、访问一个全局的
也是用上面的方法,那类型要指定成啥呢?
、映射到普通或
定义一个,有对应于的字段的属性,而且有无参数构造函数即可,比如对于{ , }可以定义一个包含;的。

这种方式下会帮你一个实例,并把对应的字段赋值过去。

的属性可以多于或者少于的属性。

可以嵌套其它复杂类型。

要注意的是,这个过程是值拷贝,如果比较复杂代价会比较大。

而且修改的字段值不会同步到,反过来也不会。

这个功能可以通过把类型加到生成降低开销,详细可参见配置介绍文档。

那有没有引用方式的映射呢?有,下面这个就是:
、映射到一个
这种方式依赖于生成代码(如果没生成代码会抛异常),代码生成器会生成这个的实例,如果一个属性,生成代码会对应的字段,如果属性也会设置对应的字段。

甚至可以通过的方法访问的函数。

、更轻量级的方式:映射到<>,<>
不想定义或者的话,可以考虑用这个,前提下和的类型都是一致的。

、另外一种方式:映射到类
这种方式好处是不需要生成代码,但也有一些问题,比如慢,比方式要慢一个数量级,
比如没有类型检查。

三、访问一个全局的
仍然是用方法,不同的是类型映射。

、映射到
这种是建议的方式,性能好很多,而且类型安全。

缺点是要生成代码(如果没生成代码会抛异常)。

要怎样声明呢?
对于的每个参数就声明一个输入类型的参数。

多返回值要怎么处理?从左往右映射到的输出参数,输出参数包括返回值,参数,参数。

参数、返回值类型支持哪些呢?都支持,各种复杂类型,,修饰的,甚至可以返回另外一个。

的使用就更简单了,直接像个函数那样用就可以了。

、映射到
这种方式的优缺点刚好和第一种相反。

使用也简单,上有个变参的函数,可以传任意类型,任意个数的参数,返回值是的数组,对应于的多返回值。

四、使用建议
、访问全局数据,特别是以及,代价比较大,建议尽量少做,比如在初始化时把要调用的获取一次(映射到)后,保存下来,后续直接调用该即可。

也类似。

、如果测的实现的部分都以和的方式提供,使用方可以完全和解耦:由一个专门的模块负责的初始化以及、的映射,然后把这些和设置到要用到它们的地方。

调用
本章节涉及到的实例均在\\下
对象
你在这样一个对象:
();
对应到是这样:
()
基本类似,除了:
1、里头没有关键字;
2、所有相关的都放到下,包括构造函数,静态成员属性、方法;
如果有多个构造函数呢?放心,支持重载,比如你要调用的带一个参数的构造函数,这么写:
('')
访问静态属性,方法
读静态属性
写静态属性
调用静态方法
('')
小技巧:如果需要经常访问的类,可以先用局部变量引用后访问,除了减少敲代码的时间,还能提高性能:
('')
访问成员属性,方法
读成员属性
写成员属性
调用成员方法
注意:调用成员方法,第一个参数需要传该对象,建议用冒号语法糖,如下
()
父类属性,方法
支持(通过派生类)访问基类的静态属性,静态方法,(通过派生类实例)访问基类的成员属性,成员方法
参数的输入输出属性(,)
调用测的参数处理规则:的普通参数算一个输入形参,修饰的算一个输入形参,不算,
然后从左往右对应调用测的实参列表;
调用测的返回值处理规则:函数的返回值(如果有的话)算一个返回值,算一个返回值,算一个返回值,然后从左往右对应的多返回值。

重载方法
直接通过不同的参数类型进行重载函数的访问,例如:
()
('')
将分别访问整数参数的和字符串参数的。

注意:只一定程度上支持重载函数的调用,因为的类型远远不如丰富,存在一对多的情况,比如的,,都对应于的,上面的例子中如果有这些重载参数,第一行将无法区分开来,只能调用到其中一个(生成代码中排前面的那个)
操作符
支持的操作符有:,,*,,,一元,<,<,,[]
参数带默认值的方法
和调用有默认值参数的函数一样,如果所给的实参少于形参,则会用默认值补上。

可变参数方法
对于的如下方法:
( , [] )
可以在里头这样调用:
(, '', '')
使用
在里定义了,里就能直接使用。

泛化(模版)方法
不直接支持,可以通过功能进行封装后调用。

枚举类型
枚举值就像枚举类型下的静态属性一样。

()
上面的函数参数是类型的
另外,如果枚举类加入到生成代码的话,枚举类将支持方法,可以实现从一个整数或者字符串到枚举值的转换,例如:
()
('')
使用(调用,,)
的调用:和调用普通函数一样
操作符:对应的操作符,把两个调用串成一个调用链,右操作数可以是同类型的或者是函数。

操作符:和相反,把一个从调用链中移除。

:属性可以用一个来赋值。

比如里头有个事件定义是这样: ;
增加事件回调
('', )
移除事件回调
('', )
位整数支持
版本位整数(,)映射到原生的未整数,而版本,相当于的标准,本身不支持位,做了个位支持的扩展库,的和都将映射到:
1、支持在里头进行位的运算,比较,打印
2、支持和的运算,比较
3、要注意的是,在扩展库中,实际上只有,也会先强转成再传递到,而对的一些运算,比较,我们采取和一样的支持方式,提供一组,详情请看文档。

复杂类型和的自动转换
对于一个有无参构造函数的复杂类型,在侧可以直接用一个来代替,该对应复杂类型的字段有相应字段即可,支持函数参数传递,属性赋值等,例如:
下结构体(也支持)定义如下:
{
;
}
{
;
;
}
某个类有成员函数如下:
( )
在可以这么调用
({ { }, })
获取类型(相当于的)
比如要获取类的信息,可以这样
()
“强”转
没类型,所以不会有强类型语言的“强转”,但有个有点像的东西:告诉要用指定的生成代码去调用一个对象,这在什么情况下能用到呢?有的时候第三方库对外暴露的是一个或者抽象类,实现类是隐藏的,这样我们无法对实现类进行代码生成。

该实现类将会被识别为未生成代码而用反射来访问,如果这个调用是很频繁的话还是很影响性能的,这时我们就可以把这个或者抽象类加到生成代码,然后指定用该生成代码来访问:
(, ())
上面就是指定用的生成代码来访问对象。

相关文档
最新文档