使用Node.js搭建AssestBundle服务器并验证AB包热更新
一、服务器部分
使用NodeJs作为服务器, 使用Express为基础网页模版。 当然, 使用其他的FTP,http服务器也可以, 基础逻辑是存放资源的位置。
1.下载Node.js
下载地址:https://nodejs.cn/download/

2.安装NodeJs软件
下一步,下一步,下一步安装即可
3.创建目录:
由于我们需要为AssestBundle建立一个服务器, 因此我们需要再本地创建一个目录来存放相关的内容。
当然, 也可以在Unity中与Assest目录的平级目录中创建WebServer目录。你可以自定义WebServer的文件夹路径 然后再WebServer中创建一个WWW_Root的目录,用来专门存放我们需要进行热更新的AB包。

4.创建express模版
使用NodeJs创建express静态网页模版。
在当前目录中,即WebServer的目录中打开cmd或者PowerShell。 你也可以直接打开cmd控制台窗口,然后切换到WebServer的目录中。下图中红色部分是标记了路径, 你只需要切换到对应的路径即可。然后输入 npm install express 进行安装express。
npm install express

5.编写NodeJs服务器启动脚本
安装完毕后express后, 编写服务器的启动脚本, 创建一个main.js的文件。
然后粘贴如下代码,
var express = require("express");
var path = require("path");
var app = express();
// http://127.0.0.1:8888/AssetBundles/Win64/Test/building.ab
// 该路径是我们前面打好包的路径==>服务器的地址
app.use("/", express.static(path.join(process.cwd(), "WWW_Root")));
// 端口号
app.listen(8888);
6.启动NodeJs服务器
在cmd或者powerShell中输入node ./main.js启动服务器。 不要关闭该窗口。

7.验证服务器是否启动成功。
打开浏览器,输入地址:端口号以及文件组成的一个完整的url地址。
例如,我将打好包的AB包放在了我的根目录, 这里需要和第二部分Unity中的打AB包的位置一致。
H:\UnityProjects\2022_ResMgr\WebServer\WWW_Root\AssetBundles\Win64\Test
由于上面写的main.js文件中的js代码是将WWW_Root映射为当前Nodejs的工作目录(cwd=current work directory), 因此,我们在浏览器中访问的路径为127.0.0.1:8888/AssetBundles/Win64/Test/house.ab。 这里的端口和图上的有点不一样, 按照实际你设置的端口为准。
127.0.0.1:8888/AssetBundles/Win64/Test/house.ab

如果你输入后的结果和上图一样, 你能保存文件,就代表着你的NodeJs服务器是启动好了的。
二、Unity部分
1.打AB包
Unity中配置AB包, 注意资源的位置。我这里是将一个房子的预制体打AB包, ab包的包名为house, 后缀名为ab。如果下图所示。 所以完整的包名为house.ab

2.拷贝ab包到服务器上
构建AB包后, 将打好的AB包放到我们前面提到的文件夹下, 也就是服务器中的目录。如下图所示, 你可以根据你点击浏览的目录来找到你需要存放的AB包。 在实际开发中,建议将ab包拷贝到StreamingAssests中, 方便进行测试。

3.使用下载并使用AB包
在Unity端口, 如何下载并使AB包呢。
思考一下, Unity需要联网, 因此,我们可以使用WWW类或者UnityWebRequest来请求一个服务器来下载文件。
当然, 如果WWW在代码中提示过时, 你应该使用UnityWebRequest来下载。需要注意的是, 下载的文件是直接加载内存中的, 因此你无法在项目的文件夹目录中找到你使用 UnityWebRequest 或者WWW下载的AB包。 下面是测试代码
代码如下:
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class GameLanch : MonoBehaviour
{
AssetBundle ab;
// ab包对应服务器的位置or文件夹
string resUrl = "http://127.0.0.1:8888/AssetBundles/Win64/Test/house.ab";
void Start()
{
// 资源检测和更新
StartCoroutine(CheckRes());
}
IEnumerator CheckRes()
{
// 构建请求的AB包的 UnityWebRequest
UnityWebRequest uwr = UnityWebRequestAssetBundle。GetAssetBundle(resUrl);
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
{
Debug.LogError(uwr.error);
}
else
{
Debug.Log("Download success!");
// 获取下载内容
ab = DownloadHandlerAssetBundle.GetContent(uwr);
if (ab != null)
{
// 从包中加载预制体
GameObject housePrefab = ab.LoadAsset<GameObject>("Assets/Arts/AssetsPakage/maps/level1/House_D_3.prefab");
if (housePrefab != null)
{
GameObject.Instantiate(housePrefab);
}
else
{
Debug.Log("mapPrefab is null");
}
}
// 卸载AB包
ab.Unload(false);
}
}
}
4.测试效果
将脚本挂载在场景中的物体上, 为了检验是否能够加载我们下载的AB包, 我们将原来存放的预制体删除。然后运行代码。下面是测试结果







![HTB:Headless[WriteUP]](https://i-blog.csdnimg.cn/direct/97ea87158c2049ac9355c6f3c85cc770.png)











