找回密码
 立即注册
查看: 347|回复: 0

将xLua应用在实际开发

[复制链接]
发表于 2023-4-11 20:30 | 显示全部楼层 |阅读模式
学习目标:

学习内容:

通过siki学院的课程 游戏热更新实战案例(基于xLua)学习到的知识
SIKI学院官网

学习时间:

8.21-8.23

学习产出:

1.配置

1.导入xLua进Unity
将xLua文件夹下面的Asset内的四个文件拖入到Unity工程的Asset下面就可以完成xLua的导入
2.配置宏
可以将代码注入到C#的程序集里面



在其Symbols下面输入HOTFIX_ENABLE
3.在编辑器阶段 调试热更新
因为xLua都是在打包时候注入HOTFIX,那么我们就得在编辑器阶段手动注入了。


先Generate Code 然后Inject 注入到Hotfix
然后就会提示你 缺少工具


我们就去从Github下载的xLua包里面找到Tools


我们发现Tools和Asset是同级目录的,那么我们导入工程的时候,就需要将Tools目录放在和工程Asset同级的目录下
但是注入的时候还是会提示错误,那么我们就需要将这三个文件从Unity的下载位置复制到工程的xLua的src目录下面的Editor里面



然后再进行Generate和Inject


提示成功
注意:我们每一次修改C#代码都需要进行GenerateCode和Inject操作
3.通过xLua去更改C#
首先 这是默认的Update函数
  1. voidUpdate(){if(++tick %50==0){
  2.                 Debug.Log(">>>>>>>>Update in C#, tick = "+ tick);}}
复制代码
然后 这是我们注册的点击事件,我们需要做到的就是在点击按钮之后我们将原先的Update函数的方法改变
  1. if(GUI.Button(newRect(10,10,300,80),"Hotfix")){
  2.                 luaenv.DoString(@"
  3.                 xlua.hotfix(CS.XLuaTest.HotfixTest, 'Update', function(self)
  4.                     local a=CS.UnityEngine.GameObject.Find('Main Camera')
  5.                         print(a.name)
  6.                 end)
  7.             ");}
复制代码
因为我们在这里面使用了Lua调用C# 所以需要在对应的Update函数加上LuaCallCSharp
  1. [LuaCallCSharp]// Update is called once per framevoidUpdate(){if(++tick %50==0){
  2.                 Debug.Log(">>>>>>>>Update in C#, tick = "+ tick);}}
复制代码
然后我们进行Generate Code 和Inject,然后我们运行。当点击按钮之后 输出的就全是MainCamera了。



打包的时候必须将Xlua里面的Examples文件夹删除,否则会花式报错
2.将捕鱼达人的功能进行修复

这个时候呢,我们就用前面所学的知识。首先我们要对C#代码进行修复,那么我们肯定要用Lua代码去修复。那么就要用到LuaCallCSharp。首先我们需要先定义出一个lua文件,去写我们的lua代码。


其次我们需要在Unity编辑器里面定义一个Cs脚本,去调用我们的lua代码。
  1. usingXLua;publicclassHotFixScript:MonoBehaviour{privateLuaEnv luaEnv;// Start is called before the first frame updatevoidStart(){
  2.         luaEnv =newLuaEnv();
  3.         luaEnv.AddLoader(MyLoader);
  4.         luaEnv.DoString("require 'fish'");}// Update is called once per framevoidUpdate(){}privatebyte[]MyLoader(refstring filePath){string absPath =@"E:\UnityProject\FishingJoy\Assets\Resources\lua"+filePath+".lua.txt";return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));//如果不是返回null,那么就执行返回的语句 也就是当前lua文本里面的语句}privatevoidOnDisable(){
  5.         luaEnv.DoString("require 'fishDispose'");}privatevoidOnDestroy(){
  6.         luaEnv.Dispose();}}
复制代码
这里OnDisable的时候,我们需要对它进行销毁。
这是由于C#还存在指向lua虚拟机里头某个函数的delegate,为了防止业务在虚拟机释放后调用这些无效(因为其引用的lua函数所在虚拟机都释放了)delegate导致的异常甚至崩溃,做了这个检查。
怎么解决?释放这些delegate即可,所谓释放,在C#中,就是没有引用:
你是在C#通过LuaTable.Get获取并保存到对象成员,赋值该成员为null;
你是在lua那把lua函数注册到一些事件事件回调,反注册这些回调;
如果你是通过xlua.hotfix(class, method, func)注入到C#,则通过xlua.hotfix(class, method, nil)删除;
要注意以上操作在Dispose之前完成。
1.修复点击宝箱领取的金币钻石太拥挤,分散一点。
首先我们对宝箱进行操作,就需要找到宝箱创造金币和钻石的代码位置。我们找到函数


在需要进行Hotfix的地方,我们定义好[LuaCallCSharp]。这样我们就可以通过lua代码去调用这个方法了,同时我们需要在这个cs文件头打上hotfix的标签


然后我们就在lua代码里面进行操作
lua调用C#里面的成员方法的时候需要将self作为参数传入
调用静态方法可以直接通过类去调用
  1. privatevoidCreatePrize(){for(int i =0; i <5; i++){GameObject go =Instantiate(gold, transform.position +newVector3(-10f+ i *30,0,0), transform.rotation);
  2.             go.transform.SetParent(cavas);GameObject go1 =Instantiate(diamands, transform.position +newVector3(0,30,0)+newVector3(-10f+ i *30,0,0), transform.rotation);
  3.             go1.transform.SetParent(cavas);}}
复制代码
  1. --1.1点击宝箱领取的金币钻石太拥挤,分散一点。local UnityEngine=CS.UnityEngine
  2. xlua.hotfix(CS.Treasour,'CreatePrize',function(self)for i=0,4,1dolocal go = UnityEngine.GameObject.Instantiate(self.gold, self.transform.position + UnityEngine.Vector3(-10+ i *40,0,0),self.transform.rotation);
  3.      go.transform.SetParent(go.transform,self.cavas);local go1 = UnityEngine.GameObject.Instantiate(self.diamands, self.transform.position + UnityEngine.Vector3(0,40,0)+UnityEngine.Vector3(-15+ i *40,0,0),self.transform.rotation);
  4.      go1.transform.SetParent(go1.transform,self.cavas);endend)
复制代码
将30-》40 扩大了之间的间距,修复好第一个bug
  1. xlua.hotfix(CS.Treasour,'CreatePrize',nil)
复制代码
释放销毁函数,避免注入到C#引起报错。
2.玩家金币钻石不够时没有相应处理。
lua调用C#里面的成员方法的时候需要将self作为参数传入 所以默认用“:”调用
调用静态方法可以直接通过类去调用 直接用“.“调用
  1. if(Input.GetMouseButtonDown(0)){
  2.             bullectAudio.clip = bullectAudios[gunLevel -1];
  3.             bullectAudio.Play();if(Butterfly){Instantiate(Bullects[gunLevel -1], attackPos.position, attackPos.rotation * Quaternion.Euler(0,0,20));Instantiate(Bullects[gunLevel -1], attackPos.position, attackPos.rotation * Quaternion.Euler(0,0,-20));}Instantiate(Bullects[gunLevel -1], attackPos.position, attackPos.rotation);if(!canShootForFree){GoldChange(-1-(gunLevel -1)*2);}
  4.             attackCD =0;
  5.             attack =false;}
复制代码
  1. --1.2玩家金币钻石不够时没有相应处理。--当我们需要访问一些类里面的私有方法和成员的时候 直接访问是没有权限的
  2. xlua.private_accessible(CS.Gun)
  3. xlua.hotfix(CS.Gun,'Attack',function(self)if UnityEngine.Input.GetMouseButtonDown(0)thenif self.gold<1+(self.gunLevel-1)*2or gold==0thenreturnend
  4.           self.bullectAudio.clip=self.bullectAudios[self.gunLevel-1]
  5.           self.bullectAudio:Play()--self.bullectAudio:Play()if self.Butterfly then
  6.              UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,20))
  7.              UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,-20))end
  8.           UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel -1], self.attackPos.position, self.attackPos.rotation);ifnot self.canShootForFree then
  9.              self:GoldChange(-1-(self.gunLevel-1)*2)end
  10.           self.attackCD=0
  11.           self.attack=falseendend)
复制代码
  1. xlua.hotfix(CS.Gun,'Attack',nil)
复制代码
3.避免UI点击操作失误
在开火前进行一个UI判断就可以实现
  1. if UnityEngine.EventSystems.EventSystem.current:IsPointerOverGameObject()thenreturnend
复制代码
  1. --1.2玩家金币钻石不够时没有相应处理。--当我们需要访问一些类里面的私有方法和成员的时候 直接访问是没有权限的
  2. xlua.private_accessible(CS.Gun)
  3. xlua.hotfix(CS.Gun,'Attack',function(self)if UnityEngine.Input.GetMouseButtonDown(0)then--2.1 与UI交互时不能发射子弹。  --这里是对象方法 如果我们用'.'那么就需要把当前对象传入if UnityEngine.EventSystems.EventSystem.current:IsPointerOverGameObject()thenreturnendif self.gold<1+(self.gunLevel-1)*2or gold==0thenreturnend
  4.           self.bullectAudio.clip=self.bullectAudios[self.gunLevel-1]
  5.           self.bullectAudio:Play()--self.bullectAudio:Play()if self.Butterfly then
  6.              UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,20))
  7.              UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,-20))end
  8.           UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel -1], self.attackPos.position, self.attackPos.rotation);ifnot self.canShootForFree then
  9.              self:GoldChange(-1-(self.gunLevel-1)*2)end
  10.           self.attackCD=0
  11.           self.attack=falseendend)
复制代码
4.技能扣钻石太多
  1. xlua.private_accessible(CS.Fire)
  2. xlua.hotfix(CS.Fire,'Start',function(self)
  3.       self.reduceDiamands =8;end)
  4. xlua.private_accessible(CS.Ice)
  5. xlua.hotfix(CS.Ice,'Start',function(self)
  6.       self.reduceDiamands =8;end)
  7. xlua.private_accessible(CS.ButterFly)
  8. xlua.hotfix(CS.ButterFly,'Start',function(self)
  9.       self.reduceDiamands =5;end)
复制代码
这里出现了一个问题,当我们修补其他脚本的时候,需要我们提前将LuaEnv配置好。比如我们在这里修补Start方法,那么我们LuaEnv的生成就必须在他前面,才可以修补,这是一个小细节。
5.使用Xlua的Util去hotfix_ex
hotfix_ex可以执行函数,然后在函数执行最后加上补丁代码
在xlua安装包里面找到这个文件,复制到我们unity工程的热更新代码同文件夹下



6.boss撞击玩家数值变动一样且不是减少是增加
  1. local util=require 'util'
  2.    
  3. xlua.private_accessible(CS.Boss)
  4. util.hotfix_ex(CS.Boss,'Start',function(self)
  5.     self.Start(self)
  6.     self.m_reduceGold=self.m_reduceGold-20end)
  7. xlua.private_accessible(CS.DeffendBoss)
  8. util.hotfix_ex(CS.DeffendBoss,'Start',function(self)
  9.     self.Start(self)
  10.     self.m_reduceGold=self.m_reduceGold-30end)
  11. xlua.private_accessible(CS.InvisibleBoss)
  12. util.hotfix_ex(CS.InvisibleBoss,'Start',function(self)
  13.     self.Start(self)
  14.     self.m_reduceDiamond=self.m_reduceDiamond-5end)
复制代码
这里就是用的hotfix_ex适用于全部代码 只有小部分需要修改的情况,但是注意,很消耗性能。
6.boss撞击玩家当钻石金币不够时会产生负数
  1. //增减金钱publicvoidGoldChange(int number){if(canGetDoubleGold){if(number >0){
  2.                 number *=2;}}
  3.         gold += number;}//增减钻石publicvoidDiamandsChange(int number){
  4.         diamands += number;}
复制代码
  1. --hotfix_ex消耗性能
  2. util.hotfix_ex(CS.Gun,'GoldChange',function(self,number)
  3.     self.GoldChange(self,number)if self.gold<-number then
  4.        self.gold=0returnendend)
  5. util.hotfix_ex(CS.Gun,'DiamandsChange',function(self,number)
  6.     self.DiamandsChange(self,number)if self.diamands<-number then
  7.        self.diamands=0returnendend)
复制代码
7.炮台3太强,且钻石没用处,不削弱,只有氪金才可使用
首先我们在前面已经修改过了发射子弹的判断,那么我们就需要在前面修改过的基础上进行修改
  1. --1.3.2.炮台3太强,且钻石没用处,不削弱,只有氪金才可使用--[[
  2.           if self.gold<1+(self.gunLevel-1)*2 or gold==0 then
  3.              return
  4.           end
  5.           --]]if self.gunLevel==3and self.diamands<3thenreturnelseif self.gunLevel~=3thenif self.gold<1+(self.gunLevel-1)*2or gold==0thenreturnendendifnot self.canShootForFree thenif self.gunLevel==3then
  6.                   self:DiamandsChange(-3)else
  7.                   self:GoldChange(-1-(self.gunLevel-1)*2)endend
复制代码
lua里面的if 和 elseif。其中elseif是需要写在一起的,要不然就会报错。
8.大鱼太多
  1. xlua.private_accessible(CS.CreateFish)
  2. xlua.hotfix(CS.CreateFish,'Update',function(self)
  3.       self:CreateALotOfFish()--单种鱼的生成if self.ItemtimeVal >=0.5then--位置随机数
  4.             self.num =UnityEngine.Mathf.Floor( UnityEngine.Random.Range(0,4))--游戏物体随机数
  5.             self.ItemNum = UnityEngine.Mathf.Floor(UnityEngine.Random.Range(1,101))local halfLength=self.fishList.Length/2local littlefishTypeIndex=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,halfLength))local bigfishTypeInde=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(halfLength,self.fishList.Length))local itemTypeIndex=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,self.item.Length))--产生气泡if self.ItemNum <20then
  6.                 self:CreateGameObject(self.item[3])end--第一种鱼42% 42if self.ItemNum <=42thenfor i=0,2,1do
  7.                 self:CreateGameObject(self.fishList[littlefishTypeIndex])end
  8.                 self:CreateGameObject(self.item[itemTypeIndex])--第二种鱼30% 43-72elseif self.ItemNum >=43and self.ItemNum <72thenfor i=0,2,1do
  9.                  self:CreateGameObject(self.fishList[bigfishTypeInde])end
  10.                 self:CreateGameObject(self.item[itemTypeIndex])--第一种bosselseif self.ItemNum >=84and self.ItemNum <=86then
  11.                 self:CreateGameObject(self.boss2)--第二种bosselseif self.ItemNum >=87and self.ItemNum <=88then
  12.                 self:CreateGameObject(self.boss)--第三种bosselseif self.ItemNum ==100then
  13.                 self:CreateGameObject(self.boss3)else
  14.                 self:CreateGameObject(self.item[0])end
  15.             self.ItemtimeVal =0;else
  16.             self.ItemtimeVal =self.ItemtimeVal+ UnityEngine.Time.deltaTime;endend)
复制代码
9.设计逻辑
扑鱼是考虑了鱼的血量与子弹的伤害来模拟概率,这样玩家体验不好,要使用传统的概率来扑鱼
  1. --1.4.1扑鱼是考虑了鱼的血量与子弹的伤害来模拟概率,这样玩家体验不好,要使用传统的概率来扑鱼
  2. xlua.private_accessible(CS.Fish)
  3. xlua.hotfix(CS.Fish,'TakeDamage',function(self,attackValue)if CS.Gun.Instance.Fire then
  4.          attackValue =  attackValue*2endlocal catchValue=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,100))if catchValue<=(50-(self.hp-attackValue))/2then
  5.           isDead =true;for i=0,8,1do
  6.               UnityEngine.GameObject.Instantiate(self.pao, self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0,45* i,0)))end
  7.           self.gameObjectAni:SetTrigger("Die")
  8.           self:Invoke("Prize",0.7);endend)
  9. xlua.hotfix(CS.Boss,'TakeDamage',function(self,attackValue)if  UnityEngine.Gun.Instance.Fire then
  10.         attackValue = attackValue*2;endlocal catchValue=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,100))if catchValue<=(attackValue*3-self.hp/10)then
  11.             UnityEngine.GameObject.Instantiate(self.deadEeffect, self.transform.position, self.transform.rotation);
  12.             CS.Gun.Instance:GoldChange(self.GetGold *10);
  13.             CS.Gun.Instance:DiamandsChange(self.GetDiamands *10);for i=0,10,1dolocal itemGo = UnityEngine.GameObject.Instantiate(self.gold, self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0,18+36*(i -1),0)));
  14.                 itemGo:GetComponent('Gold').bossPrize =true;endfor i=0,10,1dolocal itemGo1 = UnityEngine.GameObject.Instantiate(self.diamands, self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0,36+36*(i -1),0)));
  15.                 itemGo1:GetComponent('Gold').bossPrize =true;end
  16.             UnityEngine.Object.Destroy(self.gameObject);endend)
复制代码
10.按ad键进行偏移
  1. --1.4.2炮台移动是根据鼠标的水平数值滑动来模拟跟随的,改为玩家按下ad键来旋转炮台
  2. xlua.hotfix(CS.Gun,'RotateGun',function(self)if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A)then
  3.       self.transform:Rotate(UnityEngine.Vector3.forward*self.rotateSpeed)elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D)then
  4.       self.transform:Rotate(-UnityEngine.Vector3.forward*self.rotateSpeed)end
  5.    self:ClampAngle()end)
  6. xlua.private_accessible(CS.GunImage)
  7. xlua.hotfix(CS.GunImage,'RotateGun',function(self)if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A)then
  8.       self.transform:Rotate(UnityEngine.Vector3.forward*self.rotateSpeed)elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D)then
  9.       self.transform:Rotate(-UnityEngine.Vector3.forward*self.rotateSpeed)end
  10.    self:ClampAngle()end)
复制代码
11.增加新鱼
我们在进行打包的时候需要将Xlua里面自带的例子清空


然后Clear code,重新generate和inject
然后我们需要给所需要的预制体做好ab包的构造


然后我们创建文件夹Editor 就可以在里面创建AssetBundle脚本
关于AssetBundles的使用 我前面有文章讲的很清楚
  1. usingSystem.IO;usingUnityEngine;usingUnityEditor;publicclassCreateAssetBundles:MonoBehaviour{[MenuItem("Assets/Build AssetBudles")]staticvoidBuildAllAssetBundles(){string dir ="AssetBundles";if(Directory.Exists(dir)){
  2.             Directory.CreateDirectory(dir);}
  3.         BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);}}
复制代码
然后我们Unity编辑器进行打包




打包成功
然后我们在代码中要设计好怎么去调用这些预制体。我们需要在游戏开发阶段就应该提前预计到这个添加新鱼的功能,在Unity里面用C#定义好创建鱼的脚本,这样通过lua调用会很方便
  1. [LuaCallCSharp]publicstaticvoidLoadResource(string resName,string filePath){AssetBundle ab = AssetBundle.LoadFromFile(@"E:\UnityProject\FishingJoy\AssetBundles"+filePath);GameObject gameobject = ab.LoadAsset<GameObject>(resName);
  2.         prefabDict.Add(resName, gameobject);}[LuaCallCSharp]publicstaticGameObjectGetGameObject(string name){return prefabDict[name];}
复制代码
然后我们就可以在lua里面调用
  1. --2.1生成新鱼
  2. xlua.hotfix(CS.CreateFish,'Start',function(self)
  3.     CS.HotFixScript.LoadResource('level3fish3','gameobject\\enemy.ab')end)--在前面生成鱼的代码里面加入一种新的情况去生成新的鱼--2.1生成新鱼elseif self.ItemNum >=73and self.ItemNum <=83then
  4.                 newFish=CS.HotFixScript.GetGameObject('level3fish3')
  5.                 self:CreateGameObject(newFish)
复制代码
12.增加浪潮功能 切换场景
首先我们要理解,我们要添加一个浪潮,那么我们的代码
在哪呢?该何时调用这个代码呢?在哪个类?
我们之前根本没有想到需要添加这个功能,在其他的代码里面去调用也很复杂。这个时候就需要我们未雨绸缪了,在发布之前,我们就需要创建一个空白的hotfix类,里面放我们后期需要加入的代码。
  1. usingXLua;[Hotfix]publicclassHotFixEmpty:MonoBehaviour{// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){}privatevoidOnTriggerEnter(Collider other){}privatevoidBehaviourMethod(){}privatevoidBehaviourMethod1(){}privatevoidBehaviourMethod2(){}}
复制代码
这样我们就可以通过hotfix修复这个空白的类,就可以达到这个效果。
然后,我们来思考浪潮和背景切换的开发。
首先,我们需要一个浪潮的Prefab,我们创建在Unity里面,同时需要打包到资源文件里面,利用前面我们添加鱼的方式添加进去。其次,添加进去之后,我们需要做什么呢?
我们需要让他从左往右移动,然后触碰到的鱼都死亡,然后自动销毁。
其次,我们需要在哪里调用呢?很简单,创造鱼的代码里面去调用创建浪潮的方法。
设计一个bool值,可以生成浪潮就生成。设计一个计时器,当到时间就生成浪潮。
那么我们默认是可以生成浪潮的,在生成浪潮之后就设置为false不可以生成浪潮,然后在浪潮销毁的时候,设置为可以生成浪潮,这样就达到了一个循环生成一个浪潮。然后我们只需要修改Gun.Level就可以修改背景图片
  1. local canCreateNewSave=truelocal changeMapTimeval=0--2.1生成新鱼
  2. xlua.hotfix(CS.CreateFish,'Start',function(self)
  3.     CS.HotFixScript.LoadResource('level3fish3','gameobject\\enemy.ab')
  4.     CS.HotFixScript.LoadResource('SeaWave_0','gameobject\\wave.ab')end)end)
复制代码
  1. --2.0生成海浪if canCreateNewSave thenif changeMapTimeval>=60then
  2.                go=CS.HotFixScript.GetGameObject('SeaWave_0')
  3.                UnityEngine.GameObject.Instantiate(go)
  4.                canCreateNewSave=false
  5.                changeMapTimeval=0else
  6.                changeMapTimeval=changeMapTimeval+UnityEngine.Time.deltaTime
  7.            endelsereturnend
复制代码
  1. --海浪
  2. xlua.private_accessible(CS.HotFixEmpty)
  3. xlua.hotfix(CS.HotFixEmpty,'Start',function(self)
  4.     self:Invoke("BehaviourMethod",8)end)
  5. xlua.hotfix(CS.HotFixEmpty,'Update',function(self)
  6.       self.transform:Translate(-self.transform.right*4*UnityEngine.Time.deltaTime,UnityEngine.Space.World)end)
  7. xlua.hotfix(CS.HotFixEmpty,'OnTriggerEnter',function(self,other)if other.tag~="Untagged"and other.tag~="Wall"then
  8.           UnityEngine.Object.Destroy(other.gameObject)endend)
  9. xlua.hotfix(CS.HotFixEmpty,'BehaviourMethod',function(self)
  10.        CS.Gun.Instance.level=CS.Gun.Instance.level+1if CS.Gun.Instance.level==4then
  11.           CS.Gun.Instance.level=1end
  12.        canCreateNewSave =true
  13.        CS.Gun.Instance.changeAudio=true
  14.        UnityEngine.Object.Destroy(self.gameObject)end)
复制代码
3.服务器搭建


将数据放在NetBox2的目录下
首先重写Hotfix里面加载资源的方法,改为从服务器加载
  1. [LuaCallCSharp]publicvoidLoadResource(string resName,string filePath){//静态方法不可以调用协程StartCoroutine(LoadResourceCorotine(resName, filePath));//AssetBundle ab = AssetBundle.LoadFromFile(@"E:\UnityProject\FishingJoy\AssetBundles"+filePath);//GameObject gameobject = ab.LoadAsset<GameObject>(resName);//prefabDict.Add(resName, gameobject);}IEnumeratorLoadResourceCorotine(string resName,string filePath){//第四种是 使用UnityWebRequeststring uri =@"http://localhost/AssetBundles/"+ filePath;UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri);yieldreturn request.SendWebRequest();AssetBundle ab =(request.downloadHandler asDownloadHandlerAssetBundle).assetBundle;//AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);GameObject gameobject = ab.LoadAsset<GameObject>(resName);
  2.         prefabDict.Add(resName, gameobject);}
复制代码
然后我们修改了LoadResource为成员方法,那么我们之前lua脚本里面调用静态方法的办法就不可以用了,那么我就可以在GenerateFIsh脚本里面拿到对HotfixScript的引用,然后在Unity里面拖拽赋值


把生成新鱼资源加载方法修改为
  1. --2.1生成新鱼
  2. xlua.hotfix(CS.CreateFish,'Start',function(self)
  3.     self.hotFixScript:LoadResource('level3fish3','gameobject\\enemy.ab')
  4.      self.hotFixScript:LoadResource('SeaWave_0','gameobject\\wave.ab')end)
复制代码
然后Generate代码 然后Inject。发现运行正常,那么我们AssetBundle就完成工作了,可以从服务器读取数据了。
然后我们来完成lua代码的从服务器调取
  1. IEnumeratorLoadResourceCorotine(){UnityWebRequest request = UnityWebRequest.Get(@"http://localhost/fish.lua.txt");yieldreturn request.SendWebRequest();string str = request.downloadHandler.text;
  2.         File.WriteAllText(@"E:\UnityProject\FishingJoy\Assets\Resources\lua\fish.lua.txt", str);UnityWebRequest request1 = UnityWebRequest.Get(@"http://localhost/fishDispose.lua.txt");yieldreturn request1.SendWebRequest();string str1 = request1.downloadHandler.text;
  3.         File.WriteAllText(@"E:\UnityProject\FishingJoy\Assets\Resources\lua\fishDispose.lua.txt", str1);}
复制代码
利用UnityWebRequest我们就可以将数据写到我们本地的Lua文件,达到重写本地lua文件的效果。在开始游戏的时候调用协程,那么就可以从服务器拿到lua文件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 08:08 , Processed in 0.205153 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表