XLua+AssetsBundlePackage热更新(使用netbox2.8作为服务器)

1、打AB包

ab包插件:assetbundles-browser-master.zip

1)编辑器修改

将此代码放到Editor文件夹下,不然会报错

using System.Net;
using UnityEditor;
using System.IO;
using System;
//-----------------------------【构建AssetBundles资源包】-----------------------------
public class BuildAssetBundles
{
    // 菜单选项目录
    [MenuItem("Assets/Build AssetBundles")]
    static public void BuildAllAssetBundles()
    {
        // 创建文件目录
        string dir = "AssetBundles";
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        // 构建
        // 参数1:路径
        // 参数2:压缩算法,none 默认
        // 参数3:设备参数,ios,Android,windows等等
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        UnityEngine.Debug.Log("AssetBundle资源打包完成!");
}
}

然后在Assets菜单下会出现Build AssetBundles,如下:

2)设置

在场景中创建一个sphere,然后制作prefab。在预制体的Inspector面板中修改AssetBundle。

tips:new->输入名称(尽量英文,两个都要改,前一个是名称,后一个是后缀)

3)打包

这时候就完成了ab包打包设置,Assets->Build AssetsBundle即可完成打包,打包后输入文件在Assets文件同级下(先等下吼,因为还有一个文件哈)

ab包里有四个文件

2、服务器配置

使用的netbox服务器

1)下载和安装

nbsetup.rar

按照安装步骤一步步来即可,很快就安好了!!!

2)配置

第一步:在安装好的位置,新建一个文件夹,用做服务器,后续这个文件中的文件可以访问

第二步:在同级文件夹中新建一个txt,并且改名为main.box,然后用记事本打开,复制如下信息进去

Dim httpd
​
Shell.Service.RunService "NBWeb", "NetBox Web Server", "NetBox Http Server Sample"
'---------------------- Service Event ---------------------
​
Sub OnServiceStart()
    Set httpd = NetBox.CreateObject("NetBox.HttpServer")    --要加上nexbox,不然报错,找不到对象
    If httpd.Create("", 8088) = 0 Then  --端口号,注意不能被占用
        Set host = httpd.AddHost("", "\root")   --这个根据自己的来
​
        host.EnableScript = true
        host.AddDefault "default.asp"
        host.AddDefault "default.htm"
        host.AddDefault "index.asp"
        host.AddDefault "index.htm"
​
        httpd.Start
    else
        Shell.Quit 0
    end if
End Sub
​
Sub OnServiceStop()
    httpd.Close
End Sub
​
Sub OnServicePause()
    httpd.Stop
End Sub
​
Sub OnServiceResume()
    httpd.Start
End Sub

第三步:在统计文件夹中新建一个txt,改成default.asp,内容随意,可以按如下

<html><body>Hello! WEB.<br><%=Now%></body></html>

前三步完成后的文件夹层级

第四步:双击main.box,即可开启服务,通过网址“http://localhost:8088/文件名”的格式,即可访问

开启服务后可以在电脑右下角看到:

开启成功:

3、更新

准备:

下载xlua资源,并且把Tools文件放到unity工程的Assets同级,把Plugins和XLua放到Assets文件夹下,成功后会出现Xlua菜单

 

unity修改scripting define symbols为HOTFIX_ENBLE,然后回车

1)C#测试脚本

将以下两个脚本都挂载到场景中的空物体上,对应的slider和text绑定到DownLoad上,button添加事件

此脚本,后续会被lua脚本更新,正常写,唯一特殊的要添加using XLua;和在类前边添加[Hotfix],不然会报错

using UnityEngine;
using UnityEngine.EventSystems;
using XLua;
//-----------------------------【游戏脚本】-----------------------------
[Hotfix]
public class GameScript : MonoBehaviour
{
public int num1 = 100;
private int num2 = 200;
void Update()
{
    // 鼠标左键点击
    if (Input.GetMouseButtonDown(0))
    {
        if (EventSystem.current.IsPointerOverGameObject())
        {
            Debug.Log("点击到UGUI的UI界面");
        }
        else
        {
            
            //创建 cube  (后面会通过热更 lua脚本替换掉这里,使之生成Sphere)
            GameObject cubeGo = Resources.Load("Cube") as GameObject;
            // 在鼠标点击的地方实例cube
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                Debug.Log(hit.point);
                GameObject cube = GameObject.Instantiate(cubeGo, hit.point + new Vector3(0, 1, 0), transform.rotation) as GameObject;
            }
            Debug.Log("创建cube实例");
        }
​
    }
}
​
//射线 - 用于xlua调用 避免重载问题
public static bool RayFunction(Ray ray, out RaycastHit hit)
{
    return Physics.Raycast(ray, out hit);
}
}

下载资源脚本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEngine.Networking;
using XLua;
using UnityEngine.UI;
//-----------------------------【下载资源】-----------------------------
public class DownLoad : MonoBehaviour
{
// private string path = @"file://E:\WorkSpaces\Unity\XLuaFix\AssetBundles\newobj.u3d";
// private string verPath = @"http://localhost/AssetBundles/version.txt";
private string path = @"http://localhost:8088/soyuanicon.unity3d";
​
public AssetBundle assetBundle;
​
// 开始下载更新
public void StartDownLoad()
{
    Debug.Log("开始下载更新!");
    // 启动协程
    StartCoroutine(GetAssetBundle(ExcuteHotFix));
}
//-----------------------------【从服务器下载热更资源】-----------------------------
public Slider slider;
public Text progressText;//进度显示
IEnumerator GetAssetBundle(Action callBack)
{
    UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(path);
    Debug.Log("path:"+path);
    www.SendWebRequest();
    while (!www.isDone)
    {
        Debug.Log(www.downloadProgress);
        slider.value = www.downloadProgress;//下载进度
        progressText.text = Math.Floor(www.downloadProgress * 100) + "%";
        yield return 1;
    }
    // 下载完成
    if (www.isDone)
    {
        progressText.text = 100 + "%";
        slider.value = 1;
        // 隐藏UI(等待1s)
        yield return new WaitForSeconds(1);
        GameObject.Find("Canvas").SetActive(false);
    }
​
    if (www.isNetworkError || www.isHttpError)
    {
        Debug.Log("DownLoad Err: " + www.error);
    }
    else
    {
        assetBundle = DownloadHandlerAssetBundle.GetContent(www);
        TextAsset hot = assetBundle.LoadAsset<TextAsset>("luaScript.lua.txt");
        Debug.Log("hot.text=" + hot.text);
        string newPath = Application.persistentDataPath + @"/luaScript.lua.txt";
        Debug.Log("new path:"+newPath);
        
        if (!File.Exists(newPath))
        {                
            // Create后如果不主动释放资源就会被占用,下次打开会报错,所以一定要加上 .Dispose()
            File.Create(newPath).Dispose();
        }
        // 写入文件
        File.WriteAllText(newPath, hot.text);
        
        Debug.Log("下载资源成功!new Path : " + newPath);
        // 下载成功后 读取执行lua脚本
        callBack();
    }
}
​
//-----------------------------【执行热更脚本】-----------------------------
public void ExcuteHotFix()
{
    Debug.Log("开始执行热更脚本 luaScript");
    LuaEnv luaenv = new LuaEnv();
    luaenv.AddLoader(MyLoader);
    luaenv.DoString("require 'luaScript'");
}
​
// 自定义Loader
public byte[] MyLoader(ref string filePath)
{
    // 读取下载的脚本资源
    string newPath = Application.persistentDataPath + @"/" + filePath + ".lua.txt";
    Debug.Log("执行脚本路径:" + newPath);
    string txtString = File.ReadAllText(newPath);
    return System.Text.Encoding.UTF8.GetBytes(txtString);
}
}
​
​

2)Lua测试脚本

注意:这个脚本必须是txt结尾,要和上边的文件名一致(我的上边叫luaScript.lua.txt)

print("Version: 1.5")
​
xlua.private_accessible(CS.GameScript)
​
local unity = CS.UnityEngine
​
--[[
xlua.hotfix(class, [method_name], fix)
 描述 : 注入lua补丁
 class : C#类,两种表示方法,CS.Namespace.TypeName或者字符串方式"Namespace.TypeName",字符串格式和C#的Type.GetType要求一致,如果是内嵌类型(Nested Type)是非Public类型的话,只能用字符串方式表示"Namespace.TypeName+NestedTypeName";
 method_name : 方法名,可选;
 fix : 如果传了method_name,fix将会是一个function,否则通过table提供一组函数。table的组织按key是method_name,value是function的方式。
--]]
-- 替换掉 GameScript 的 Update 方法
​
xlua.hotfix(CS.GameScript,"Update",
function(self)
    print("lua 开始执行")
    if unity.Input.GetMouseButtonDown(0) then
        local go = unity.GameObject.Find("ScriptsManager")  --挂载脚本的空物体的名称
        --print("获取场景中的物体:"..go)
        -- 获取assetBundle资源
        local ab = go:GetComponent("DownLoad").assetBundle  --下载资源的脚本名称
        -- 读取创建 Sphere 
        local SphereGo = ab:LoadAsset("Sphere") --打ab包的物体名称
        --print("通过ab获取的soyuan:"..SphereGo)   --这句有时会报错,注释掉哦
        -- 在鼠标点击的位置实例Sphere
        local ray = unity.Camera.main:ScreenPointToRay (unity.Input.mousePosition)
        local flag,hit = CS.GameScript.RayFunction(ray)
        if flag then
            print(hit.transform.name)
            local sphere = unity.GameObject.Instantiate(SphereGo)
            sphere.transform.localPosition = hit.point + unity.Vector3(0,1,0)
        end
    
    end
end
)

场景中的关系:

 

3)打ab包

第一步:把lua脚本也和sphere设置同样的AssetBundle名称和后缀,然后一起打包(忘了的话,看第一部分哦)

第二步:把打包的ab包上传到netbox服务器

第三步:回到unity,然后在XLua菜单

按图示顺序执行:

执行完之后即可运行

执行更新前:

执行更新后

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值