- 一个简单、高效、易扩展的 AssetBundle管理工具
- Editor、Runtime均支持同步、异步、委托、携程
- 支持各个模式切换(无需修改代码)
- 支持自定义资源加密
- 支持分布式构建(支持mod)
- 支持 shader 变体收集
- 支持 构建 spriteatlas
- 支持打包/加载Unity无法识别的文件
- 支持打包流程自定义(自定义分包、版本规划、结束流程、自定义标签)
- 包含本地资源服务器
- 支持快速版本切换,回退
- 支持资源模糊搜索
- 支持子资源加载
- 支持资源懒卸载/内存大小控制
各个模式切换无需修改代码
- 0 编辑器模拟加载 (纯粹编辑器模拟)
- 1 纯粹的C#空包, (注意:本地不会有任何ab)
- 2 发布 正常流程包 (比模式1 多一个版本检查)
- 3 发布 游戏前期的体验包 (把资源拷贝到stream)
- 4 边玩边下载
- 5 先准备一部分,后续靠下载
模式/流程 | 编辑器模拟 | 纯C#空包 | 正常流程 | 前期的体验 | 边玩边下载 | 先准备一部分 | |
---|---|---|---|---|---|---|---|
打包 | |||||||
选择FastMode | ✔ | ||||||
打包资源 | ✔ | ✔ | ✔ | ✔ | ✔ | ||
拷贝资源到stream | ✔ | 按tag拷贝 | |||||
上传资源到服务器 | ✔ | ✔ | ✔ | ✔ | |||
加载 | |||||||
设置AssetsSetting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
拷贝资源到沙盒路径 | ✔ | ✔ | |||||
版本检查 | ✔ | 可选 | 可选 | ||||
下载变化资源 | ✔ | 可选 | |||||
初始化 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
正常加载 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
///写一个 class 继承于 AssetsSetting
public abstract class AssetsSetting
{
///下载的路径
protected virtual string GetBaseUrl() {}
///自定义 bundle 去哪里下载
public virtual string GetUrlByBundleName(string buildTarget, string bundleName){}
///自定义 版本文件 去哪里下载
public virtual string GetVersionUrl(string buildTarget){}
/// 文件比对方式
public virtual FileCompareType GetFileCheckType() {}
/// 下载等待
public virtual int GetWebRequestTimeout() {}
///资源加密方式
public virtual IAssetStreamEncrypt GetEncrypt() {}
///是否自动卸载
public virtual bool GetAutoUnloadBundle() {}
/// 如果本地没有是否需要保存文件
public virtual bool GetSaveBundlesWhenPlaying(){}
/// 自定义的资源生命周期管理,bundle和asset均可以
public virtual IAssetLife GetAssetLife(){}
}
///自定义的资源设置
AssetsSetting set;
///要加载的资源的路径
string path;
///设置AssetsSetting
Assets.SetAssetsSetting(set);
///拷贝资源到沙盒路径
await Assets.CopyDLCFromSteam();
///版本检查,得到所有可用版本
var op = await Assets.VersionCheck();
///选择一个想要的版本和本地比较,可以选择值比较部分构建
///可选项,只比较部分满足tag的打包组
var compare = await op.Compare(op.versions.Count - 1);
///下载需要更新的bundle
for (int i = 0; i < compare.add.Count; i++)
await Assets.DownLoadBundle(compare.add[i].name);
for (int i = 0; i < compare.change.Count; i++)
await Assets.DownLoadBundle(compare.change[i].name);
///初始化
///传入版本号,按照该版本号加载
///不传入版本号就会直接使用本地的版本,本地没有就会使用服务器最新版本
///允许只初始化部分tag的资源组
await Assets.InitAsync();
///正常加载
var asset = await Assets.LoadAssetAsync(path);
///获取要加载的资源
var sp = asset.GetAsset<Sprite>();
///加载场景
var sceneAsset = await Assets.LoadSceneAssetAsync(path);
await sceneAsset.LoadSceneAsync(LoadSceneMode.Additive);
///加载Unity无法识别的资源
var asset = await Assets.LoadAssetAsync(path);
RawObject raw = asset.GetAsset<RawObject>();
Debug.Log(raw.bytes.Length);
///加载子资源
var mainAsset = await Assets.LoadAssetAsync(path);
var sp = mainAsset.GetSubAsset<Sprite>("a_1");
///卸载资源
Assets.Release(asset)
- 1 打开窗口 [MenuItem("Tools/WooAsset/Window")]
- 2 设置好打包相关参数
- 3 点击 [MenuItem("Tools/WooAsset/Bundle/Build")]
//个性化打包流程
public interface IAssetBuild
{
//自定义版本规则
string GetVersion(string settingVersion, AssetTaskContext context);
//自定义 资源 Tag (可以按照tag加载一组资源)
IReadOnlyList<string> GetTags(EditorAssetData info);
// 自定义资源分组
void Create(AssetTagCollection tags,List<EditorAssetData> assets, Dictionary<EditorAssetData, List<EditorAssetData>> dpsDic, List<BundleGroup> result);
//自定义打包结束之后需要执行的任务
//比如输出一些Log、上传文件到服务器等
List<AssetTask> GetPipelineFinishTasks(AssetTaskContext context);
//更具一个路径返回资源类型
AssetType GetAssetType(string path);
}
//个性化加密
public interface IAssetStreamEncrypt
{
byte[] Encode(string bundleName, byte[] buffer);
byte[] Decode(string bundleName, byte[] buffer);
}
- 左侧:一些快速处理
- 右侧:切换下方页签
- Runtime:快速模式以及本地资源服务器
- Editor:打包时候的相关设置参数
参数 | 简介 | ||
---|---|---|---|
Runtime | |||
Asset Mode | |||
Mode | 资源加载的模式(Normal/Fast) | ||
Simulated Asset Server | |||
Enable Server | 是否开启资源服务器 | ||
Server Directory | 资源服务器的根路径 | ||
Server Port | 资源服务器监听的端口 | ||
Editor | |||
Shader Variant | |||
shaderVariantDirectory | shader变体保存的文件夹 | ||
Sprite Atlas | |||
atlasPaths | 所有需要打包的图集的文件夹 | ||
packSetting | 图集打包设置 | ||
textureSetting | 图集打包图片设置 | ||
PlatformSetting | 图集打包平台设置 | ||
Build | |||
version | 这一次打包出去的带的版本号 | ||
bundle size | 打包出来的最大的bundle 大小 | ||
force rebuild | 强制重新打包 | ||
ignore extend | 通关文件后缀排除不需要打包的文件 | ||
buildGroups | 所有需要打包的文件夹 | ||
Asset Build | 打包流程的个性化 | ||
encrypt | 加密方式 | ||
history directory | 上一次打包的缓存 | ||
compress | 压缩格式 | ||
Output Path | 输出路径 | ||
Build Target | 打包的平台 |
可以方便的看见
- 设置好shaderVariantDirectory
- 点击 [MenuItem("Tools/WooAsset/Help/ShaderVariant")]
- 设置好atlasPaths,packSetting,textureSetting,PlatformSetting
- 点击 [MenuItem("Tools/WooAsset/Help/SpriteAtlas")]
- 设置好 Enable Server ,Server Directory ,Server Port
- 注意
- 资源服务器只会在运行状态且NormalMode状态下打开
- 如果资源服务器的配置不为空,在打包资源的时候会把输出文件拷贝过去
- 每一个机器上面都需要有所有的 buildGroup
- 哪些 需要构建,就把 build 打勾
- 每一个机器打包完毕之后无需任何处理,直接把output下的文件上传文件服务器
- 不需要分多个文件夹
- 所有的版本资源都在同一个文件夹
- 如果想要的到所有资源的所有版本,可以直接解析10a8d8bae0d67598c045791dad2f6599这个文件
- 打包时候 IAssetBuild.GetAssetType 无法识别的文件需要返回 AssetType.Raw
- AssetType.Raw 类型的文件不会打到 assetbundle中。打包的是他对应的RawObject
- 加载时候 asset.GetAsset< RawObject >();
- RawObject 的字段 bytes 存储的就是那个无法识别的文件的字节流
- 获取到这个 bytes之后自行转换到需要使用的类型即可
- .lua 文件,unity无法识别就可以这么做(xlua)
- unity可以识别的也可以这么做(程序集),比如一个程序集直接记录他的bytes(ILRuntime)
public class AssetsSearch
{
///以下是交集
///搜索所有名字包含 assetName ,并且包含所有 tag 的资源
public static IReadOnlyList<string> IntersectNameAndTag(string assetName, params string[] tags){}
///搜索所有包含所有 tag 的资源
public static IReadOnlyList<string> IntersectTag(params string[] tags){}
///搜索所有名字包含 assetName ,类型符合,并且包含所有 tag 的资源
public static IReadOnlyList<string> IntersectTypeAndNameAndTag(AssetType type, string assetName, params string[] tags){}
///类型符合,并且包含所有 tag 的资源
public static IReadOnlyList<string> IntersectTypeAndTag(AssetType type, params string[] tags){}
///以下是并集
///搜索所有名字或者 tag 包含 nameOrTags 的并集
public static IReadOnlyList<string> Union(params string[] nameOrTags){}
///搜索所有 tag 包含 tags 的并集
public static IReadOnlyList<string> UnionTag(params string[] tags){}
///搜索所有名字 包含 names 的并集
public static IReadOnlyList<string> UnionName(params string[] names){}
///搜索所有名字或者 tag 包含 tags 且名字包含 assetName 的并集
public static IReadOnlyList<string> UnionNameAndTag(string assetName, params string[] tags){}
///获取这一类型,且名字 包含tag 的并集
public static IReadOnlyList<string> UnionTypeAndNameAndTag(AssetType type, string assetName, params string[] tags){}
///获取这一类型并且包含tag的并集
public static IReadOnlyList<string> UnionTypeAndTag(AssetType type, params string[] tags){}
/// 获取这一类型的所有资源
public static IReadOnlyList<string> AssetPathByType(AssetType type){}
}
- 内置了一个LRU,本质上就是自定义资源生命周期
- 可以实现 bundle 不自动卸载,到达一定大小在开始卸载
- 如果内存不足时候,最早被使用的资源会被优先卸载
- 内存设置的别太小,容易出现资源丢失