(带完整demo)Unity3d热更新xlua基于Unity2018.2.2和xlua2.1.14(小白提升干货)

下载xlua

https://github.com/Tencent/xLua

安装xlua到unity工程

1 解压后的目录如下在这里插入图片描述
2 将Assets目录下的文件复制到Unity工程的Assets目录下
3 将Tools整个目录复制到Unity工程与Assets的同目录下
4 配置宏
在File/Build Settings/Player Settings,设置Scripting_Define_Symbols的值为HOTFIX_ENABLE
如上步骤后,会发现菜单上多了一个XLua菜单
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

运行测试

1 打开XLua/Examples/08_Hotfix的 Hotfix_Test
2 在菜单XLua下,先点击Generate Code等待编译完成后,再点击Hotfix Inject In Editor,再次等待编译
3 运行,观察到控制台输出为update in c#
4 点击Hotfix,观察到控制台输出

LUA: <<<<<<<<Update in lua, tick = 9350 UnityEngine.Debug:Log(Object)
XLua.StaticLuaCallbacks:Print(IntPtr) (at
Assets/XLua/Src/StaticLuaCallbacks.cs:629)
XLua.LuaDLL.Lua:lua_pcall(IntPtr, Int32, Int32, Int32)
XLua.DelegateBridge:PCall(IntPtr, Int32, Int32, Int32) (at
Assets/XLua/Src/DelegateBridge.cs:138)
XLua.DelegateBridge:__Gen_Delegate_Imp14(Object) (at
Assets/XLua/Gen/DelegatesGensBridge.cs:340)
XLuaTest.HotfixTest:Update()
这样我们就实现了lua调用c#
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新建一个修复脚本HotFixTest1

这里用来加载lua代码到luaEnv中执行,目录是相对路径,放在与Assets同目录下
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
public class HotFixTest1 : MonoBehaviour {
    private LuaEnv luaEnv;
    private void Awake()
    {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(HandleCustomLoader);
        luaEnv.DoString("require'fix'");
    }
    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {

    }

    private byte[] HandleCustomLoader(ref string filepath)
    {
        string absPath = filepath + ".lua.txt";
        return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
    }
    private void OnDisable()
    {
        luaEnv.DoString("require'fixDispose'");
    }
    private void OnDestroy()
    {
        luaEnv.Dispose();
    }


}

新建lua文件测试

1 fix.lua.txt与项目Assets同目录下

--test
UnityEngine = CS.UnityEngine
UnityEngine.Debug.Log("test")

2 fixDispose.lua.txt暂时为空 与项目Assets同目录下

3 将上一步的HotFixTest1脚本挂到场景任意物体上,比如相机上

4 在菜单XLua下,先点击Generate Code等待编译完成后,再点击Hotfix Inject In Editor,再次等待编译
5 观察到输出了test
在这里插入图片描述

为demo搭建一个加载游戏场景

1 场景很简单,一个Slider
在这里插入图片描述
2 新建脚本LoadGame

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class LoadGame : MonoBehaviour {
    public Slider slider;
    
    public string luaPath = @"http://212.64.12.155/unity/demo2/fix.lua.txt";
    // Use this for initialization
    void Start () {
        LoadGameMethod();
    }

    private void LoadGameMethod()
    {
        StartCoroutine(StartLoading(1));
        StartCoroutine(LoadResFromServerCorotine());
    }
    private IEnumerator StartLoading(int scene)
    {
        int displayProgress = 0;
        int toProgress = 0;
        AsyncOperation op = SceneManager.LoadSceneAsync(scene);
        op.allowSceneActivation = false;
        while (op.progress < 0.9f)
        {
            toProgress = (int)op.progress * 100;
            while (displayProgress < toProgress)
            {
                ++displayProgress;
                SetLoadingPercentage(displayProgress);
                yield return new WaitForEndOfFrame();
            }
        }

        toProgress = 100;
        while (displayProgress < toProgress)
        {
            ++displayProgress;
            SetLoadingPercentage(displayProgress);
            yield return new WaitForEndOfFrame();
        }
        op.allowSceneActivation = true;
    }
    private void SetLoadingPercentage(float v)
    {
        slider.value = v / 100;
    }
    IEnumerator LoadResFromServerCorotine()
    {
        UnityWebRequest request = UnityWebRequest.Get(luaPath);
        yield return request.SendWebRequest();
        string str = request.downloadHandler.text;
        string localFilePath = @"./fix.lua.txt";
        File.WriteAllText(localFilePath, str);
    }
    // Update is called once per frame
    void Update () {
		
	}
}

3将LoadGame脚本挂到MainCamera 上,然后吧Slider赋值上
在这里插入图片描述

为demo搭建主场景测试

1 创建text显示当前版本
2 新建GameManager物体
3 新建Manager脚本,内容如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using XLua;
using UnityEngine.Networking;
[Hotfix]
public class Manager : MonoBehaviour {
    public Text uitext;
    public GameObject parent;
    public static Dictionary<string, GameObject> prefabDict = new Dictionary<string, GameObject>();

    // Use this for initialization
    public string title = "1.0版本";
    [LuaCallCSharp]
    void Start () {
	}
	
	// Update is called once per frame
	void Update () {
        setText(title);
	}
   public void setText(string text)
    {
        uitext.text = text;
    }
    public void LoadResource(string resName, string filePath)
    {
        StartCoroutine(LoadResourceCorotine(resName, filePath));
    }
    //产生游戏物体
    private void CreateGameObject(GameObject go)
    {
        GameObject goPrefab = Instantiate(go, Vector3.zero, Quaternion.identity);
        goPrefab.transform.parent = parent.transform;
        goPrefab.transform.localPosition = Vector3.zero;
    }
    IEnumerator LoadResourceCorotine(string resName, string filePath)
    {
        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(@"http://212.64.12.155/unity/demo2/AssetBundles/" + filePath);
        yield return request.SendWebRequest();
        AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;

        GameObject go = ab.LoadAsset<GameObject>(resName);
        prefabDict.Add(resName, go);
        CreateGameObject(go);
        Debug.Log("resName=" + resName + ";goName=" + go.name);
    }

}

在这里插入图片描述
4 将Manager脚本挂到GameManager物体上
在这里插入图片描述
5 新建一个text作为prefab,拖到prefabs文件夹,并在右下角设置AssetBundle属性
在这里插入图片描述
好了之后删除场景中的ABTest

完善我们的lua文件

1 fix.lua.txt

--test
UnityEngine = CS.UnityEngine
UnityEngine.Debug.Log("test")
--version to 1.1
xlua.private_accessible(CS.Manager)
xlua.hotfix(CS.Manager,'Start',function(self)
self.title='Version 1.3'
self:LoadResource('ABTest','ab\\test.ab')
end)

2 fixDispose.lua.txt

--dispose
xlua.hotfix(CS.Manager,'Start',nil)

写好之后,将这两个文件上传到服务器,
比如我的服务器位置为:http://xxxxx:80/unity/demo2

新建一个AssetBundle打包工具

1 在Assets目录下新建Editor目录,新建CreateAssetBundle脚本
在这里插入图片描述
2 代码如下:(注意,博主的环境为mac,如果你是windows用户,请更改BuildTarget为StandaloneWindows)


using UnityEditor;
using System.IO;
public class CreateAssetBundle {
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string dir = "./AssetBundles";
        if(Directory.Exists(dir) == false)
        {
            Directory.CreateDirectory(dir);
        }
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None,
            BuildTarget.StandaloneOSX);
    }

}

3 回到unity编译,在Assets目录下会出现Build AssetBundles菜单
在这里插入图片描述
点击构建,在工程Assets目录下会出现我们要的ab包
在这里插入图片描述
4 将ab包上传到服务器根目录

运行及一些bug总结

在这里插入图片描述
bugs:
1 如果遇到bug请检查自己的环境版本
2 请注意路径是否正确
3 如果报错,请重新在XLua菜单,重新生成和注入
4 AssetsBundle的构建应该在Xlua环境构建之后,否则会出错

更多参考

【Unity】场景异步加载的进度条制作

https://blog.csdn.net/sinat_20559947/article/details/50000455

Xlua官网

https://github.com/Tencent/xLua

使用指南

https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md

官方FAQ

https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/faq.md

菜鸟教程-Lua教程

http://www.runoob.com/lua/lua-tutorial.html

如何评价腾讯在Unity下的xLua(开源)热更方案?

https://www.zhihu.com/question/54344452/answer/139413144?group_id=800755990562734080

IL(中间语言)

http://blog.csdn.net/dodream/article/details/4726421

玩转xLua的热补丁

http://gad.qq.com/article/detail/42303

xlua的配置

https://github.com/Tencent/xLua/blob/master/Assets/XLua/Examples/ExampleGenConfig.cs

更多

1

学习热更新需要大家到达的程度:

1.什么是Lua,lua的基本用法与语法。
2.什么是ab包,ab包的打包,加载,下载。
3.xlua的一些基础内容,如何开启一个Lua虚拟机工作坏境,如何加载lua文件,怎样在c#里去调lua,在Lua中去调c#。

2 如果有任何问题,可以下方评论,或者加QQ1577432674与本人交流
3 宣传一下交流群:在这里插入图片描述
4 宣传一下个人公众号:edsgame,更多游戏开发干货
在这里插入图片描述
5 完整项目工程链接(也可以加群,群文件有)
链接:https://pan.bai删了我du.com/s/1zUc5L0iUQw5aojXy6a5Ylw 密码:g8yo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章