Xlua学习笔记

2023-11-15

本篇笔记是记录"游戏热更新实战案例(基于xLua)"的学习笔记。
1、Xlua的环境搭建
1)导入Xlua插件
上Github上下载Xlua插件,将Xlua解压,将Asset下的所有文件拷贝到当前项目目录Asset下。拷贝与Asset同级目录下的Tools到该该项目中一样的位置。
2)unity菜单栏 File=》BuildSetting=》playsetting =》OtherSettings=》Scripting Define Symbols 输入HOTFIX_ENABLE
在这里插入图片描述
搭建功能就完成了。
3)复制相关DLL文件
在这里插入图片描述
PS:该捕鱼项目是2017的uinity版本,我用2018打开Xlua部署环境报错,用2017则无问题,原因可能是Xlua版本没有更新,大家学习的时候注意一下版本问题。

2、使用Xlua修复游戏中存在的BUG。
1)如何通过lua文件实现热更新?
首先创建一个调用脚本,挂在物体上,代码如下。这个是固定格式,相关API不明白的话可以自行查阅。


public class HotFixScript : MonoBehaviour {

    private LuaEnv luaEnv;

	void Start () {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(MyLoader);
        luaEnv.DoString("require'fish'");
	}
	
	void Update () {
		
	}

    private byte[] MyLoader(ref string filePath)
    {
        string absPath = @"C:\Users\Administrator\Desktop\XluaProjects\PlayerGamePackage\"+filePath+".lua.txt";
        return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
    }
    //在OnDestroy前调用,释放已经注册的委托
    private void OnDisable()
    {
        luaEnv.DoString("require'fishDispose'");
    }

    private void OnDestroy()
    {
        luaEnv.Dispose();
    }
}

然后在绝对路径创建lua文件。
在这里插入图片描述
然后在可能会出现问题的类上打上[Hotfix]标签
在这里插入图片描述
在需要修改的函数方法上打上[LuaCallCSharp]标签
在这里插入图片描述
执行到这里的时候就会调用Lua脚本。

功能需求以及解决方法的相关代码。
1.1点击宝箱领取的金币钻石太拥挤,分散一点

--1.1点击宝箱领取的金币钻石太拥挤,分散一点
--常用的变量可以定义一个局部变量去接收
--[[
Lua调用C#中的类要添加前缀CS.
C#中调用自身对象是this.XXX
但是lua中需要加上self.
此处想调用自身的金币, C#完整代码是this.gold,但是在lua中要写全,为self.gold。--]]
local UnityEngine = CS.UnityEngine
--标准格式,第一个参数是C#中打上标签的类(即你想修改的类,第二个参数是要修改的方法,第三个参数是自身)
--此处金币拥挤,我们只需查看代码,将相关间隔的相关代码数值增大即可。
xlua.hotfix(CS.Treasour,'CreatePrize',function(self)
	for i=0,4,1 do
		local go = UnityEngine.GameObject.Instantiate(self.gold,self.transform.position + UnityEngine.Vector3(-10+i*40,0,0),self.transform.rotation)
		go.transform.SetParent(go.transform,self.cavas)
		local go1 = UnityEngine.GameObject.Instantiate(self.diamands,self.transform.position + UnityEngine.Vector3(0,40,0)+ UnityEngine.Vector3(-10+i*40,0,0),self.transform.rotation)
		go1.transform.SetParent(go1.transform,self.cavas)
	end
end)

在这里插入图片描述
lua中代码将30改为40,即可完成这个初步的简单任务。

1.1玩家金币钻石不够时没有相关处理
这个问题处理起来有个小坑,C#代码中调用了私有变量,lua中直接调用会报错,需要加上相关代码,如下。
另外lua中调用自身的方法为XX.Func(self) 或者XX:Func()

--如果想访问私有变量需要加上下面这一行代码,此处bullectAudio是私有变量
xlua.private_accessible(CS.Gun) 
xlua.hotfix(CS.Gun,'Attack',function(self)
	if UnityEngine.Input.GetMouseButtonDown(0) then	

		if UnityEngine.EventSystems.EventSystem.current:IsPointerOverGameObject() then
			return
		end

		if self.gold<1+(self.gunLevel-1)*2 or self.gold==0 then
			return
		end

		self.bullectAudio.clip = self.bullectAudios[self.gunLevel-1]
		--self.bullectAudio.Play(self) 两种调用自身方法的形式
		self.bullectAudio:Play()
			
			if self.Butterfly then
				UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,20))
				UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,-20))
			end

			UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation)

			if not self.canShootForFree then
				self:GoldChange(-1-(self.gunLevel-1)*2)
			end
			self.attackCD =0
			self.attack = false
		end
end)

–1.2 技能扣除钻石太多
解决方法,一样查看相关代码,然后修改
在这里插入图片描述
发现代码写在Start中,这里要注意,我们调用luaEnv的脚本要写在Awake中,补丁需要在代码前执行。写在Start顺序可能会出问题从而导致无效。

xlua.private_accessible(CS.Fire)
xlua.hotfix(CS.Fire,'Start',function(self)
	self.reduceDiamands = 8
end)

–1.2boss撞击玩家数值变动一样且不是减少是增加
依旧和之前一样,找到相关代码,用lua修改
在这里插入图片描述
但这次使用更简便的方法,不需要重写全部,而是在执行完之后再执行我们的lua代码
需要注意,util的这个文件要和当前的lua脚本在同级目录下,这个文件可以下xlua文件下种搜索到。复制过来粘贴即可。注销委托的时候格式与之前一样,依旧是xlua.hotfix(CS.Boss,‘Start’,nil)

local util = require 'util'
xlua.private_accessible(CS.Boss)
util.hotfix_ex(CS.Boss,'Start',function(self)
	self:Start()
	self.m_reduceGold = self.m_reduceGold-10;
end)

–1.3 boss撞击玩家当钻石金币不够时产生负数
这个与之前有点区别,需要传参,改动方法如下
在这里插入图片描述

util.hotfix_ex(CS.Gun,'GoldChange',function(self,number)
	self:GoldChange(number)
	if self.gold <-number then
		self.gold = 0
		return	
	end
end)

–1.4捕鱼概率修改
捕鱼代码中用到了GetComponent方法,但是lua中不支持泛型,好在C#中也支持参数为string的GetComponent方法,穿的参数改为string类型即可。

itemGo:GetComponent('Gold').bossPrize = true

–1.4游戏操作方式更改
无新的知识点,lua重写代码即可。

–2.0新增海浪
这个比较麻烦,首先需要一个预制体,其次这个预制体上还要有脚本代码。解决方法,先创建一个空的脚本,里面有几个常用的空方法,挂在预制体上,然后打包成AssetBundle文件上传至服务器,加载的时候可以先从服务器下载到本地指定位置,然后再读取。

//空的C#脚本,留给lua脚本实现
[Hotfix]
public class HotFixEmpty : MonoBehaviour {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}
    private void BehaviourMethod()
    {

    }

    private void OnTriggerEnter(Collider other)
    {
        
    }

}
--2.0新增海浪
--lua脚本实现功能。
xlua.private_accessible(CS.HotFixEmpty)
xlua.hotfix(CS.HotFixEmpty,'Start',function(self)
	self:Invoke('BehaviourMethod',8)
end)

xlua.hotfix(CS.HotFixEmpty,'Update',function(self)
	self.transform:Translate(-self.transform.right*4*UnityEngine.Time.deltaTime,UnityEngine.Space.World)
end)

xlua.hotfix(CS.HotFixEmpty,'OnTriggerEnter',function(self,other)
	if other.tag~='Untagged' and other.tag~='Wall' then
	UnityEngine.Object.Destroy(other.gameObject)
	end
end)

xlua.hotfix(CS.HotFixEmpty,'BehaviourMethod',function(self)
	CS.Gun.Instance.level = CS.Gun.Instance.level + 1
	if CS.Gun.Instance.level == 4 then
		CS.Gun.Instance.level = 1
	end
	canCreateNewFish = true
	CS.Gun.Instance.changeAudio = true
	UnityEngine.Object.Destroy(self.gameObject)
end)

总结:使用Xlua时需要注意的坑。
1、普通成员方法与静态成员方法调用的区别。
静态成员方法直接XX.Function()即可。有参数直接写在括号里 XX.Function(a,b…)
普通成员方法调用格式为 XX.Function(self)有参数写在self后面 XX.Function(self,a,b)
或者XX:Function()有参数直接写在括号里XX:Function(a,b)
2、lua中不存在new,如果C#脚本中存在new,直接无视即可。
3、lua中不支持泛型,如果C#中用到了泛型,请替代为string参数,或者单独写一个方法获取值,lua调用方法获得返回值
4、过于复杂的代码建议C#实现,lua直接调用即可,虽然lua也能实现,但是比较麻烦且性能消耗不如C#,例如

[LuaCallCSharp]
    public void LoadResource(string resName,string filePath)
    {
        StartCoroutine(LoadResourceCorotine(resName, filePath));
    }

    IEnumerator LoadResourceCorotine(string resName, string filePath)
    {
        UnityWebRequest request= UnityWebRequest.GetAssetBundle(@"http://localhost/AssetBundles/" + filePath);
        yield return request.SendWebRequest();
        //AssetBundle ab = AssetBundle.LoadFromFile(@"C:\Users\Administrator\Desktop\XluaProjects\FishingJoy\AssetBundles\" + filePath);
        AssetBundle ab =(request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        GameObject gameObject = ab.LoadAsset<GameObject>(resName);
        prefabDict.Add(resName, gameObject);
    }
xlua.hotfix(CS.CreateFish,'Start',function(self)
	self.hotFixScript:LoadResource('level3fish3','gameobject\\enemy.ab')
	self.hotFixScript:LoadResource('SeaWave','gameobject\\wave.ab')
end)

这里lua调用起来就很方便。
5、lua主要是用来修复紧急BUG,不建议做大改动,例如2.0版本开发的海浪功能,先把资源打包好上传到服务器,代码全部是lua写,开发效率较低。
如果预制体上挂有脚本,本地一定要先有脚本在解压,不然AssetBundle解压出来没有脚本则会丢失,无法完成相应的功能。

资源图片较多,文件较大,想看源码的建议移步siki学院搜索热更新

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Xlua学习笔记 的相关文章

  • 为什么这个 Lua 优化 hack 会提高性能?

    我正在寻找一个描述提高 Lua 性能的各种技术的文档 http www lua org gems sample pdf脚本代码 我很震惊竟然需要这样的技巧 虽然我引用的是 Lua 但我在 Javascript 中也见过类似的 hack 为什
  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • 了解静态链接嵌入式lua环境中lua扩展dll的构建/加载

    我有一个相对复杂的 lua 环境 我试图了解以下内容如何工作 起始设置包括以下两个模块 主要应用 无lua环境 DLL 静态链接到lua lib 包括解释器 该 dll 被加载到主应用程序中 并运行 lua 控制台解释器和可从控制台访问的
  • 我应该用 C++ 封装 Lua 代码的哪些代码?

    我终于将 LuaBind 配置为与我的 C 项目一起使用 我最近发现 Tiled 地图编辑器可以选择将文件导出为 lua 所以我想尝试一下 我将使用什么代码来封装下面粘贴的代码以使其与我的 C RPG 项目一起使用 return versi
  • 循环直到在表中找到 2 个特定值?

    我试图找到一种更聪明的方法来解决这个问题 这是与游戏相关的代码的摘录 它循环遍历每个背包的每个插槽 直到找到铲子和绳子 local continue local foundShovel foundRope for i 0 Container
  • 在 Corona sdk 上保存高分?

    我想保存游戏中创建的高分 并且当玩家点击高分按钮时可以在主菜单中看到 有人可以帮助我吗 您可以使用SQLITE https docs coronalabs com api library sqlite3 index html将高分保存到数据
  • 如何在aerospike中获取ttl为-1的记录集?

    我在aerospike中有很多记录 我想获取ttl为 1的记录 请提供解决方案 只是为了澄清 设置TTL 为 1 https github com aerospike aerospike client go blob master docs
  • Lua-迭代嵌套表

    我已经学习 Lua 几个星期了 这一次又一次成为我的症结所在 我尝试阅读有关该主题的帖子和书籍 我使用 Lua 查询软件监控系统 Nimsoft 我的数据以表格形式返回给我 我不会发布整个输出 但这里有一个我认为可以描述结构的片段 表参考是
  • 如何在 Lua 中实现 OO?

    Lua 没有内置对 OO 的支持 但它允许您自己构建它 您能否分享一些实现面向对象的方法 请为每个答案写一个例子 如果您有更多示例 请发布另一个答案 我喜欢将 OOP 视为容器 对象 内的数据封装以及可以使用该数据完成的操作子集 还有很多内
  • 如何在Conky中实现一个基本的Lua功能?

    我正在尝试向我的 Conky 添加一个函数 该函数打印字符串的长度以用于调试目的 代码位于名为的文件内test lua 非常简单 function test word return string len word end 我这样加载它 在我
  • 在lua中组合两个函数

    我刚开始学习lua 所以我的要求可能是不可能的 现在 我有一个接受函数的方法 function adjust focused window fn local win window focusedwindow local winframe w
  • lua中的权限问题

    是否需要在 corona build settings 中设置一些特定权限才能将高分永久保存在文件中 每次运行代码时都会出现 权限被拒绝 的错误 如何纠正这个错误 这是我尝试过的代码 function read score local f1
  • 在Lua中获取前一天的日期

    谁能告诉我如何使用 Lua 获取 YYYY MM DD 格式的前一天日期 即 一个片段 它将返回运行当天的前一天的日期 Try print os date Y m d os time 24 60 60 严格来说 这只能保证在 POSIX 系
  • 如何使用 srlua 制作可执行的 Lua 脚本?

    我的主要目标是使我的 lua 文件成为可执行文件或使其成为咬代码 最好是两者皆有 我正在尝试 srlua 但在自述文件中它告诉我要做的事情 对于Windows 您需要首先创建srlua exe和glue exe 然后为每个 你想把Lua程序
  • Openresty 中的并发模型是什么?

    我很难理解 openresty 或 nginx 的并发模型 我读了Lua变量作用域 http wiki nginx org HttpLuaModule Lua Variable Scope 它解释了变量的生命周期 但它没有说明对它们的并发访
  • 如何终止Lua脚本?

    如何终止 Lua 脚本 现在我在 exit 方面遇到问题 我不知道为什么 这更像是一个 Minecraft ComputerCraft 问题 因为它使用了包含的 API 这是我的代码 while true do if turtle dete
  • 关闭 Löve2D 中的抗锯齿功能

    我在用着L ve2D http love2d org用于编写一个小游戏 L ve2D 是 Lua 的开源游戏引擎 我遇到的问题是 当您在非整数位置绘制精灵时 某些抗锯齿过滤器会自动应用于精灵 love graphics draw sprit
  • 在 Awesome-wm 中为特定应用程序设置窗口布局

    如何配置很棒 以便它可以启动两个窗口对齐的新应用程序 如下所示 xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx 其中 x 是 pidgin 中的对话窗口 是好友列表窗口 一般来说 我想指定右窗口的宽度
  • 如何在 Lua - Lightroom 插件中使用 HMAC

    首先我要提的是我对 Lua 真的很陌生 如果你认为我的问题太愚蠢 请耐心等待 这是我的要求 我需要使用 HMAC sha256 进行 Lightroom 插件开发 因为我使用它是为了安全 我试图使用这个但没有运气https code goo
  • 如何使用 Lua 运行可执行文件?

    我有一个可执行文件想要使用 Lua 运行 我该怎么做 似乎无法在任何地方找到有关此的任何文档 您可以使用 Lua 原生的 执行 命令 Example os execute c temp program exe 资料来源 Lua 指南 os

随机推荐

  • 2022护网日记,护网工作内容、护网事件、告警流量分析

    作者主页 士别三日wyx 作者简介 CSDN top100 阿里云博客专家 华为云享专家 网络安全领域优质创作者 2022护网日记 一 监控设备 二 工作内容 三 安全事件 1 失陷主机排查 2 后门网站修复 四 告警流量分析 1 信息泄露
  • 7-4 快速排序

    7 4 快速排序 20 分 注 由于是用map计数暴力实现的 所以当数据量大的时候就会WA 众所周知 Keven是一个ACMer 他今天刚刚学会了快速排序 他非常开心 因为他可以快速的找到区间第K小的数字了 但是同为ACMer的JOJO看不
  • Linux系统下查看被杀死进程的信息

    通过dmesg 命令分析原因 软件在运行时显示 进程被杀死 首先通过命令查看被杀死的进程的情况 dmesg egrep i B100 killed process 显示 在被杀死的时候该进程占用的内存 22588 717326 Killed
  • string的length()与size()方法有什么区别

    正如文档http en cppreference com w cpp string basic string中所述 string的length 和size 方法只是同义词而已 size 方法与其他的STL容器一致 比如vector map等
  • 数据库和缓存双写一致性

    文章目录 前言 1 常见方案 2 先写缓存 再写数据库 3 先写数据库 再写缓存 3 1 写缓存失败了 3 2 高并发下的问题 3 3 浪费系统资源 4 先删缓存 再写数据库 4 1 高并发下的问题 4 2 缓存双删 5 先写数据库 再删缓
  • 锐捷交换机生成树

    生成树 Ruijie config spanning tree 打开Spanning Tree协议 锐捷设备默认起开了STP Ruijie config spanning tree mode mstp rstp stp 切换Spanning
  • Java学习之Struts 2.x

    与传统的Struts1 x相比 Struts2 x允许使用更普通的 传统的Java对象作为Action Action的execute方法不再与Servlet API耦合 因而更易测试 支持更多的视图技术 基于AOP思想的拦截器机制 提供了极
  • Downloading C/C++ language components (Linux / x86_64)

    Problem The report from vscode as shown in the title cannot be canceled and keep showing there This happens when I am tr
  • Linux 安装gcc和运行代码(Ubuntu为例)

    目录 一 安装gcc 二 gcc编译 运行代码 首先检测网络连通性 一 安装gcc 1 打开虚拟机终端 安装gcc 输入 sudo apt install gcc 2 安装完成后检查 输入 gcc version 如果出现以下内容 则说明安
  • 基于沙猫群优化算法的线性规划求解matlab程序

    基于沙猫群优化算法的线性规划求解matlab程序 1 沙猫群优化算法 沙猫的中文学名叫沙丘猫 俗名沙漠猫 与荒漠猫名字相似 但却是两种不同的猫科动物 沙猫生活在茫茫沙漠里 主要分布在分布于非洲北部 阿拉伯半岛中部和西南亚 沙猫的家园 是贫瘠
  • Node.js 从零开发 web server博客项目[koa2重构博客项目]

    web server博客项目 Node js 从零开发 web server博客项目 项目介绍 Node js 从零开发 web server博客项目 接口 Node js 从零开发 web server博客项目 数据存储 Node js
  • 【Python脚本抢红包】用Python写了一个自动抢红包工具,今年过年准备大干一场

    话说又要过年了 现在过年可没有小时候的味道了 小时候只顾着放鞭炮 现在只顾着各个群里蹲红包 但是手动抢肯定没戏 毕竟手can谁也没办法 那就只能试试能不能通过编程的方式实现自动化抢红包了 跟小编一样财迷的铁汁们 可以往下滑了 代码文末可取
  • 基于计算机视觉的智能制造:实现对智能制造的实时监控和调度

    作者 禅与计算机程序设计艺术 1 简介 智能制造 Intelligent Manufacturing 是在不断进步的科技和技术领域里 将智能技术应用到制造领域中去 实现机器 设备 材料的自动化和精准化过程 提升生产效率 降低成本 节约能源和
  • ESX虚拟机克隆后提示设备"0"的配置无效

    一般是克隆后mac地址与原网卡mac地址不符导致的 解决办法 下载虚拟机 vmx文件 修改其中的跟网卡eth0相关的mac地址跟实际mac相符 实在不行就删除网卡0 再添加一块网卡 有时候网卡驱动类型不符也不会报类似的错误 虚拟网卡一般有三
  • 区块链100讲:Hyperledger Fabric 中的链码(智能合约)

    1 链码概念 网络运行环境我们已经启动完成 现在我们从开发者的角度来认识一下完成交易所必须的智能合约 在 Hyperledger Fabric 中被称之为 Chaincode 也就是链上代码 的相关知识 以便于理解账本中的数据到底是通过什么
  • Windows 找不到文件 ‘gpedit.msc‘。请确定文件名是否正确后,再试一次。(已解决)

    今天在使用命令gpedit msc打开组策略编辑器报错 Windows 找不到文件 gpedit msc 请确定文件名是否正确后 再试一次 离谱 我都没改过设置什么的 后来找到解决办法 重新安装 桌面新建txt文档 文档里输入内容 echo
  • 程序员-接单网站

    远程工作平台 1 靠山云 https www kaoshanyun com 靠山云平台新型远程办公兼职平台 为中高端程序员 产品经理和设计师等等互联网相关人员提供稳定的线上工作机会 包括自由工作 远程工作和兼职工作 还支持按需雇佣 工作模式
  • C++ 程序抛异常产生的 core 文件,无法显示正确的函数调用栈信息(备忘)

    问题 比如 如下程序 include
  • Windows与Mac中idea常用快捷键转换

    从 Windows 过度到 Mac 必备快捷键对照表 Mac 键盘符号说明 Command Shift Caps Lock Option Control Return Enter Delete 向前删除键 Fn Delete 上箭头 下箭头
  • Xlua学习笔记

    本篇笔记是记录 游戏热更新实战案例 基于xLua 的学习笔记 1 Xlua的环境搭建 1 导入Xlua插件 上Github上下载Xlua插件 将Xlua解压 将Asset下的所有文件拷贝到当前项目目录Asset下 拷贝与Asset同级目录下