unity案例 mysql lua_通过Xlua实现unity热更新的一个小例子

通过Xlua实现unity热更新的一个小例子

一.介绍

​ 热更新是指在更新游戏资源或者逻辑的时候不需要开发者将游戏再打包、发布、玩家重新下载安装包,而是可以通过将需要更新的资源打包成AssetBundle文件发布到服务器,然后游戏程序通过下载服务器的AssetBundle替换本地文件来达到游戏更新的流程。

​ 打包出来的unity制作的游戏,如果在代码(代码用的是c#语言)上有需要更改的地方,必须重新打包,因为c#语言需要重新编译为dll文件,而如果是lua语言编写,则不需要重新编译。

​ 如果想让lua和c#之间互相调用,可以借用一些开源的Lua插件,比如xLua,toLua。在例子中使用的是xLua插件

二.准备工作

1.xLua

下载xlua_v2.1.14.zip

将Tools文件夹复制到工程项目,与Assets同级

将Assets文件夹中的文件复制到工程项目的Assets文件夹里

2.将自己的电脑变成一个本地的服务器

打开控制面板-选择管理工具-IIS-在网站处右键添加网站-填写相关项-启动新建的网站

其中应用程序池要选择DefaultAppPool,物理路径为你希望服务器所在的路径,端口可以填一个二位数字

设置完成后,在浏览器中搜索localhost:端口即可查看服务器存放的文件

3.安装执行Lua的IDE

4.在unity中加入HOTFIX_ENABLE标签

选择Edit->Project Setting->Player 右边Inspector列表中

三.打包AssetBundle

1.将需要打包成AB文件的资源添加AssetBundle标签

其中,要打在同一个AB包的资源,标签要求一致

2.编写打包代码

using UnityEditor;

using System.IO;

public class CreateAssetBundles

{

[MenuItem("Assets/BuildAssetBundles")]

static void BuildAllAssetBundles()

{

//要写两个'/',一个是转义符,

string dir = "F://Web Server//AssetBundles";

if (Directory.Exists(dir) == false)

{

Directory.CreateDirectory(dir);

}

//参数 打包路径,压缩方式,打包平台

BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

}

}

这里我服务器的路径为F:\Web Server

上述脚本可在Editor模式下运行,不需要挂在GameObject上

点击BuildAssetBundles即可将需要打包成AB文件的资源上传到服务器

四.热更新

给步骤三中的cube添加一个用来测试热更新的脚本,这个脚本会在游戏时让cube的scale扩大到原来的2倍,rotation的x,y,z都增加30。类上方添加特性Hotfix使其可热更新。

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using XLua;

[Hotfix]

public class ChangeSelf : MonoBehaviour

{

public Vector3 currentScale;

public Quaternion currentRotation;

public Vector3 laterScale;

public Quaternion laterRotation;

// Start is called before the first frame update

void Start()

{

currentScale = this.transform.localScale;

currentRotation = this.transform.localRotation;

ChangeScale(currentScale);

ChangeRotation(currentRotation);

this.transform.localScale = laterScale;

this.transform.localRotation = laterRotation;

}

public void ChangeScale(Vector3 scale)

{

laterScale = scale * 2;

//this.transform.localScale = laterScale;

}

public void ChangeRotation(Quaternion rotation)

{

laterRotation = Quaternion.Euler(rotation.eulerAngles.x+30, rotation.eulerAngles.y+30, rotation.eulerAngles.z+30);

//this.transform.localRotation = laterRotation;

}

}

在服务器中添加热更新的lua脚本,路径:

代码:

--hotfix中的参数分别为要进行热更新的类,要更新的方法,方法所在的类(function中的第一个参数指方法所在的类,其他参数为要更新的方法的参数)

xlua.hotfix(CS.ChangeSelf,'ChangeScale',function(self,scale)

self.laterScale = scale * 0.5

end

)

local Quaternion = CS.UnityEngine.Quaternion

local rot = CS.UnityEngine.Quaternion() --新建一个对象

xlua.hotfix(CS.ChangeSelf,'ChangeRotation',function(self,rotation)

self.laterRotation = Quaternion.Euler(rotation.eulerAngles.x+60,rotation.eulerAngles.y+60,rotation.eulerAngles.z+60)

end

)

注意:在SciTE中编写完lua脚本,保存的后缀是lua,如果要被unity识别,需要增加txt的后缀

上述的热更新旨在让cube的scale缩小到原来的一半,rotation的x,y,z都增加60

五.加载

1.加载AssetBundle

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.Networking;

public class LoadAssetBundles : MonoBehaviour

{

// Start is called before the first frame update

IEnumerator Start()

{

//这里的地址是服务器端的地址 localhost:后的数字是端口

string url = @"http://localhost:81/AssetBundles/luatestcube.unity3d";

while (Caching.ready == false)

{

yield return null;

}

using (var www = WWW.LoadFromCacheOrDownload(@"http://localhost:81/AssetBundles/luatestcube.unity3d", 2))

{

yield return www;

if (!string.IsNullOrEmpty(www.error))

{

Debug.Log(www.error);

yield return null;

}

var assetBundle = www.assetBundle;

//var asset = assetBundle.mainAsset;

GameObject cubePrefab = assetBundle.LoadAsset("luatestcube");

Instantiate(cubePrefab);

}

}

}

该脚本可挂在空物体上

2.加载lua脚本

using System.Collections;

using System.Collections.Generic;

using System.Text;

using UnityEngine;

using XLua;

public class HotFixTests : MonoBehaviour

{

private LuaEnv m_kLuaEnv;

// Start is called before the first frame update

void Start()

{

//xlua虚拟机

m_kLuaEnv = new LuaEnv();

//查找指定路径下lua热更新文件

string path = Application.persistentDataPath + "/ChangeSelf.lua.txt";

//用协程下载读取文件内容

StartCoroutine(DownloadFile(path));

}

public IEnumerator DownloadFile(string path)

{

WWW www = new WWW(path);

yield return www;

if (www.isDone)

{

System.IO.StreamReader sr = new System.IO.StreamReader(path, Encoding.UTF8);

if (sr != null)

{

//执行lua中的语句

m_kLuaEnv.DoString(sr.ReadToEnd());

}

}

}

}

using System.Collections;

using System.Collections.Generic;

using System.IO;

using UnityEngine;

public class WWWTexts : MonoBehaviour

{

private string urlPath = @"http://localhost:81/Xlua/ChangeSelf.lua.txt";//资源网络路径

private string file_SaveUrl;//资源保存路径

private FileInfo file;

// Start is called before the first frame update

void Start()

{

file_SaveUrl = Application.persistentDataPath + "/ChangeSelf.lua.txt";

file = new FileInfo(file_SaveUrl);

StartCoroutine(DownFile(urlPath));

}

IEnumerator DownFile(string url)

{

WWW www = new WWW(url);

yield return www;

if (www.isDone)

{

Debug.Log("下载完成");

byte[] bytes = www.bytes;

CreatFile(bytes);

}

}

///

/// 创建文件

///

///

void CreatFile(byte[] bytes)

{

//将服务器的文件按字节写入保存路径所在文件

Stream stream;

stream = file.Create();

stream.Write(bytes, 0, bytes.Length);

stream.Close();

stream.Dispose();

}

}

这两个脚本挂在同一个空物体上

3.运行

每次修改完c#脚本或者lua脚本后,都要先点击第一个,再点击第三个,然后才能运行。

如果成功执行会输出一下两条日志

然后就能运行unity了,运行后发现cube的scale和rotation都实现了lua脚本中的更改,而不是c#脚本中的更改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值