diff --git a/Docs/AssetBuilder.md b/Docs/AssetBuilder.md new file mode 100644 index 0000000..b401b5a --- /dev/null +++ b/Docs/AssetBuilder.md @@ -0,0 +1,133 @@ +# 资源构建 + +![image](https://github.com/tuyoogame/YooAsset/raw/main/Docs/Image/AssetBuilder-img1.jpg) + +### 界面介绍 + +**Build Output** + +构建输出的目录,会根据Unity编辑器当前切换的平台自动划分构建结果。 + +**Build Version** + +构建版本号,也是资源版本号,版本号必须大于零。 + +**Compression** + +资源包的压缩方式。 + +**Append Extension** + +构建的资源包文件名是否包含后缀格式。 + +**Force Rebuild** + +是否为强制重新构建,如果不勾选则为增量构建模式。注意:强制重建会删除当前平台下所有的补丁包文件。 + +**Buildin Tags** + +标记为安装包里的资源标签列表。构建成功后,会将相关标记的资源包拷贝到StreamingAssets文件夹下。 + +**Build** + +点击Build按钮会开始构建流程,构建流程分为多个节点顺序执行,如果某个节点发生错误,会导致构建失败。错误信息可以在控制台查看。 + +### 资源包加密 + +编写继承IAssetEncrypter接口的加密类。注意:加密类文件需要放置在Editor文件夹里。 + +````C# +public class AssetEncrypter : IAssetEncrypter +{ + /// + /// 检测资源包是否需要加密 + /// + bool IAssetEncrypter.Check(string filePath) + { + // 对配置表相关的资源包进行加密 + return filePath.Contains("Assets/Config/"); + } + + /// + /// 对数据进行加密,并返回加密后的数据 + /// + byte[] IAssetEncrypter.Encrypt(byte[] fileData) + { + int offset = 32; + var temper = new byte[fileData.Length + offset]; + Buffer.BlockCopy(fileData, 0, temper, offset, fileData.Length); + return temper; + } +} +```` + +### 补丁包 + +构建成功后会在输出目录下找到补丁包文件夹,该文件夹名称为本次构建时指定的资源版本号。 + +补丁包文件夹里包含补丁清单和资源包文件以及说明文件,资源包文件都是以文件的哈希值命名。 + +![image](https://github.com/tuyoogame/YooAsset/raw/main/Docs/Image/AssetBuilder-img4.jpg) + +### 补丁清单 + +补丁清单是一个Json格式的文本文件,里面包含了所有资源包的信息,例如:名称,版本,大小,CRC等。 + +![image](https://github.com/tuyoogame/YooAsset/raw/main/Docs/Image/AssetBuilder-img2.jpg) + +### Jenkins支持 + +如果需要自动化构建,可以参考如下代码范例: + +````c# +private static void BuildInternal(BuildTarget buildTarget) +{ + Debug.Log($"开始构建 : {buildTarget}"); + + // 打印命令行参数 + int buildVersion = GetBuildVersion(); + bool isForceBuild = IsForceBuild(); + Debug.Log($"资源版本 : {buildVersion}"); + Debug.Log($"强制重建 : {isForceBuild}"); + + // 构建参数 + string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot(); + AssetBundleBuilder.BuildParameters buildParameters = new AssetBundleBuilder.BuildParameters(); + buildParameters.IsVerifyBuildingResult = true; + buildParameters.OutputRoot = defaultOutputRoot; + buildParameters.BuildTarget = buildTarget; + buildParameters.BuildVersion = buildVersion; + buildParameters.CompressOption = ECompressOption.LZ4; + buildParameters.AppendFileExtension = false; + buildParameters.IsForceRebuild = isForceBuild; + buildParameters.BuildinTags = "buildin"; + + // 执行构建 + AssetBundleBuilder builder = new AssetBundleBuilder(); + builder.Run(buildParameters); + + // 构建完成 + Debug.Log("构建完成"); +} + +// 从构建命令里获取参数 +private static int GetBuildVersion() +{ + foreach (string arg in System.Environment.GetCommandLineArgs()) + { + if (arg.StartsWith("buildVersion")) + return int.Parse(arg.Split("="[0])[1]); + } + return -1; +} +private static bool IsForceBuild() +{ + foreach (string arg in System.Environment.GetCommandLineArgs()) + { + if (arg.StartsWith("forceBuild")) + return arg.Split("="[0])[1] == "true" ? true : false; + } + return false; +} +```` + diff --git a/Docs/AssetCollector.md b/Docs/AssetCollector.md new file mode 100644 index 0000000..74169ec --- /dev/null +++ b/Docs/AssetCollector.md @@ -0,0 +1,74 @@ +# 资源收集 + +![image](https://github.com/tuyoogame/YooAsset/raw/main/Docs/Image/AssetCollector-img1.jpg) + +### 界面介绍 + +**着色器收集** + +勾选收集所有着色器复选框后,打包系统会自动收集所有依赖的材质球使用的着色器,并将这些着色器打进一个AssetBundle文件内。 + +**Directory** + +收集的资源目录,目录下的所有文件将会根据打包规则和过滤规则进行打包。 + +**PackRule** + +打包规则,规则可以自定义扩展。下面是内置的打包规则: + +1. PackExplicit 目录下的资源文件会各自打进自己的资源包里。 +2. PackDirectory 目录下的资源文件会被打进一个资源包里。 +3. PackRawFile 目录下的资源文件会被处理为原生资源包。 + +自定义扩展范例 + +````c# +public class PackDirectory : IPackRule +{ + string IPackRule.GetAssetBundleLabel(string assetPath) + { + return Path.GetDirectoryName(assetPath); //"Assets/Config/test.txt" --> "Assets/Config" + } +} +```` + +**FilterRule** + +过滤规则,规则可以自定义扩展。下面是内置的过滤规则: + +1. CollectAll 收集目录下的所有资源文件 +2. CollectScene 只收集目录下的场景文件 +3. CollectPrefab 只收集目录下的预制体文件 +4. CollectSprite 只收集目录下的精灵类型的文件 + +自定义扩展范例 + +````c# +public class CollectScene : IFilterRule +{ + public bool IsCollectAsset(string assetPath) + { + return Path.GetExtension(assetPath) == ".unity"; + } +} +```` + +**DontWriteAssetPath** + +资源目录下的资源对象不写入清单 + +**AssetTags** + +资源标签列表(多个标签使用分号间隔) + +### 配置表 + +点击Import按钮可以导入外部的XML配置表,配置表规范如下图: + +````xml + + + + +```` + diff --git a/Docs/AssetDeploy.md b/Docs/AssetDeploy.md new file mode 100644 index 0000000..899a678 --- /dev/null +++ b/Docs/AssetDeploy.md @@ -0,0 +1,3 @@ +# 资源部署 + +监听 \ No newline at end of file diff --git a/Docs/Image/AssetBuilder-img4.jpg b/Docs/Image/AssetBuilder-img4.jpg new file mode 100644 index 0000000..62963d9 Binary files /dev/null and b/Docs/Image/AssetBuilder-img4.jpg differ diff --git a/Docs/Image/Settings-img1.jpg b/Docs/Image/Settings-img1.jpg new file mode 100644 index 0000000..321cd78 Binary files /dev/null and b/Docs/Image/Settings-img1.jpg differ diff --git a/Docs/QuickStart.md b/Docs/QuickStart.md new file mode 100644 index 0000000..b91727d --- /dev/null +++ b/Docs/QuickStart.md @@ -0,0 +1,27 @@ +# 快速开始 + +**下载安装** + +1. 通过OpenUPM安装 +2. 通过Packages安装 +3. 通过GIT安装 + +**系统需求** + +支持版本: Unity2018.4+ + +支持平台: Windows、OSX、Android、iOS + +开发环境: .NET4.x + +**目录结构** + +```` +Assets +└─ YooAsset + ├─ Editor 编辑器源码目录 + ├─ Runtime 运行时源码目录 + ├─ LICENSE 版权文档 + └─ README 说明文档 +```` + diff --git a/Docs/Settings.md b/Docs/Settings.md new file mode 100644 index 0000000..fdb56f7 --- /dev/null +++ b/Docs/Settings.md @@ -0,0 +1,20 @@ +# 全局配置 + +![image](https://github.com/tuyoogame/YooAsset/raw/main/Docs/Image/Settings-img1.jpg) + +通过右键创建配置文件(Project窗体内右键 -> Create -> YooAsset -> Create Setting) + +**注意**:请将配置文件放在Resources文件夹下 + +**Asset Bundle File Variant** : AssetBundle资源包后缀名 + +**Raw File Variant** : 原生资源包后缀名 + +**Patch Manifest File Name** : 补丁清单文件名 + +**Patch Manifest Hash File Name** : 补丁清单哈希文件名 + +**Unity Manifest File Name** : Unity构建的清单名称 + +**Readme File Name** : 说明文件名称 + diff --git a/Docs/YooAssetInit.md b/Docs/YooAssetInit.md new file mode 100644 index 0000000..10c9392 --- /dev/null +++ b/Docs/YooAssetInit.md @@ -0,0 +1,66 @@ +# 初始化 + +资源系统的运行模式支持三种:编辑器模拟模式,单机运行模式,联机运行模式。 + +````C# +// 资源系统初始化方法,根据不同的模式,我们传递不同的创建参数类 +YooAssets.InitializeAsync(CreateParameters parameters); +```` + +**编辑器模拟模式** + +在编辑器下,不需要构建资源包,来模拟运行游戏。 + +注意:该模式只在编辑器下起效 + +````c# +private IEnumerator InitializeYooAsset() +{ + var createParameters = new YooAssets.EditorPlayModeParameters(); + createParameters.LocationRoot = "Assets/GameRes"; + yield return YooAssets.InitializeAsync(createParameters); +} +```` + +**单机运行模式** + +对于不需要热更新资源的游戏,可以使用单机运行模式。 + +注意:该模式需要构建资源包 + +````c# +private IEnumerator InitializeYooAsset() +{ + var createParameters = new YooAssets.OfflinePlayModeParameters(); + createParameters.LocationRoot = "Assets/GameRes"; + yield return YooAssets.InitializeAsync(createParameters); +} +```` + +**联机运行模式** + +对于需要热更新资源的游戏,可以使用联机运行模式,该模式下初始化参数会很多。 + +注意:该模式需要构建资源包 + +- LocationRoot : 资源定位的根路径,所有通过代码加载的资源文件都需要放在资源定位的根路径下。 +- DecryptServices : 如果资源包在构建的时候有加密,那么需要提供实现IDecryptServices接口的实例类。 +- ClearCacheWhenDirty : 安装包在覆盖安装的时候,是否清空沙盒缓存文件夹。 +- IgnoreResourceVersion : 是否忽略资源版本号,请参考进阶教程。 +- DefaultHostServer : 默认的资源服务器IP地址。 +- FallbackHostServer : 备用的资源服务器IP地址。 + +````c# +private IEnumerator InitializeYooAsset() +{ + var createParameters = new YooAssets.HostPlayModeParameters(); + createParameters.LocationRoot = "Assets/GameRes"; + createParameters.DecryptServices = null; + createParameters.ClearCacheWhenDirty = false; + createParameters.IgnoreResourceVersion = false; + createParameters.DefaultHostServer = "http://127.0.0.1/CDN1/Android"; + createParameters.FallbackHostServer = "http://127.0.0.1/CDN2/Android"; + yield return YooAssets.InitializeAsync(createParameters); +} +```` + diff --git a/Docs/YooAssetLoader.md b/Docs/YooAssetLoader.md new file mode 100644 index 0000000..b9ce148 --- /dev/null +++ b/Docs/YooAssetLoader.md @@ -0,0 +1,120 @@ +# 资源加载 + +在加载资源对象的时候只需要提供相对路径,统一约定该相对路径名称为:location + +资源加载接口: + +- YooAssets.LoadAssetSync() 同步加载资源对象接口 +- YooAssets.LoadSubAssetsSync() 同步加载子资源对象接口 +- YooAssets.LoadAssetAsync() 异步加载资源对象接口 +- YooAssets.LoadSubAssetsAsync() 异步加载子资源对象接口 +- YooAssets.LoadSceneAsync() 异步加载场景接口 + +**加载路径的匹配方式** + +````C# +// 不带扩展名的模糊匹配 +YooAssets.LoadAssetAsync("Audio/bgMusic"); + +// 带扩展名的精准匹配 +YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); +```` + +**异步加载范例** + +````C# +// 委托加载方式 +void Start() +{ + AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); + handle.Completed += Handle_Completed; +} +void Handle_Completed(AssetOperationHandle handle) +{ + AudioClip audioClip = handle.AssetObject as AudioClip; +} +```` +````C# +// 协程加载方式 +void Start() +{ + this.StartCoroutine(AsyncLoad()); +} +IEnumerator AsyncLoad() +{ + AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); + yield return handle; + AudioClip audioClip = handle.AssetObject as AudioClip; +} +```` +````C# +// Task加载方式 +async void Start() +{ + await AsyncLoad(); +} +async Task AsyncLoad() +{ + AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); + await handle.Task; + AudioClip audioClip = handle.AssetObject as AudioClip; +} +```` + +**资源卸载范例** + +````C# +void Start() +{ + AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); + + ... + + handle.Release(); +} +```` + +**预制体同步加载范例** + +````C# +var handle = YooAssets.LoadAssetSync(location); +GameObject go = handle.InstantiateObject; +```` + +````c# +var handle = YooAssets.LoadAssetSync(location); +GameObject go = UnityEngine.Object.Instantiate(handle.AssetObject as GameObject); +```` + +**子对象同步加载范例** + +例如:通过TexturePacker创建的图集,如果需要访问图集的精灵对象,可以通过子对象加载接口。 + +````c# +var handle = YooAssets.LoadSubAssetsSync(location); +foreach (var asset in handle.AllAssets) +{ + Debug.Log($"Sprite name is {asset.name}"); +} +```` + +**场景异步加载范例** + +````c# +void Start() +{ + // 场景加载参数 + SceneInstanceParam param = new SceneInstanceParam(); + param.LoadMode = UnityEngine.SceneManagement.LoadSceneMode.Single; + param.ActivateOnLoad = true; + + AssetOperationHandle handle = YooAssets.LoadSceneAsync("Scene/Login", param); + handle.Completed += Handle_Completed; +} +void Handle_Completed(AssetOperationHandle handle) +{ + SceneInstance instance = handle.AssetInstance as SceneInstance; + Debug.Log(instance.Scene.name); +} +```` + diff --git a/Docs/YooAssetUpdater.md b/Docs/YooAssetUpdater.md new file mode 100644 index 0000000..b8101fc --- /dev/null +++ b/Docs/YooAssetUpdater.md @@ -0,0 +1,113 @@ +# 资源更新 + +**更新补丁清单** + +对于联机运行模式,在初始化资源系统之后,需要立刻更新资源清单。 + +在此之前,需要获取更新的资源版本号,一般通过HTTP访问游戏服务器来获取。 + +````c# +private IEnumerator UpdatePatchManifest() +{ + int updateResourceVersion = 123; + int timeout = 30; + UpdateManifestOperation operation = YooAssets.UpdateManifestAsync(updateResourceVersion, timeout); + yield return operation; + + if(operation.Status == EOperationStatus.Succeed) + { + //更新成功 + } + else + { + //更新失败 + Debug.LogError(operation.Error); + } +} +```` + +**补丁包下载** + +在补丁清单更新完毕后,就可以更新资源文件了。 + +根据产品需求,可以选择更新全部资源,或者只更新部分资源。 + +````c# +private PatchDownloader _downloader; + +/// +/// 创建下载器 +/// +private void CreateDownloader() +{ + string[] tags = { "buildin", "config" }; + int downloadingMaxNum = 10; + int failedTryAgain = 3; + _downloader = YooAssets.CreateDLCDownloader(tags, 10, 3); + if (_downloader.TotalDownloadCount == 0) + { + //没有需要下载的资源 + } + else + { + //需要下载的文件总数和总大小 + int totalDownloadCount = _downloader.TotalDownloadCount; + long totalDownloadBytes = _downloader.TotalDownloadBytes; + } +} + +/// +/// 更新下载器 +/// +private void UpdateDownloader() +{ + if(_downloader != null) + _downloader.Update(); +} + +/// +/// 开启下载 +/// +private IEnumerator Download() +{ + //注册下载回调 + _downloader.OnPatchFileDownloadFailedCallback = OnPatchFileDownloadFailed; + _downloader.OnDownloadProgressCallback = OnDownloadProgressUpdate; + _downloader.OnDownloadOverCallback = OnDownloadOver; + _downloader.Download(); + yield return _downloader; + + //检测下载结果 + if (_downloader.DownloadStates == EDownloaderStates.Succeed) + { + //下载成功 + } + else + { + //下载失败 + } +} + +/// +/// 文件下载失败 +/// +private void OnPatchFileDownloadFailed(string fileName) +{ + Debug.LogError($"File download failed : {fileName}"); +} + +/// +/// 下载进度的更新 +/// +private void OnDownloadProgressUpdate(int totalDownloadCount, int currentDownloadCount, long totalDownloadSizeBytes, long currentDownloadSizeBytes) +{ +} + +/// +/// 下载结束,成功或失败 +/// +private void OnDownloadOver(bool isSucceed) +{ +} +```` + diff --git a/README.md b/README.md index 1ac2fec..18f5f8d 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,43 @@ # YooAsset -YooAsset是基于Unity3D引擎的资源管理插件。 +YooAsset是一个基于Unity3D引擎的资源管理插件。 -# 支持版本 -Unity2018.4 && Unity2019.4 && Unity2020.3 - -# 开发环境 -C# && .Net4.x - -# 特点 -#### 强大灵活的打包系统 +## 特点 +**强大灵活的打包系统** 可以自定义打包策略,可以自定义冗余规则,自动分析依赖实现资源零冗余,基于资源对象的资源包依赖管理方案,避免了资源包之间循环依赖的问题。 -#### 安全高效的分包方案 +**安全高效的分包方案** 基于资源对象的标签分包方案,自动对依赖资源包进行分类,避免人工维护成本。可以非常方便的实现零资源安装包,或者全量资源安装包。 -#### 灵活高效的加密方案 +**灵活高效的加密方案** 提供多种加密策略,可以自定义加密规则,基于Unity官方的高效解密方案。 -#### 基于引用计数方案 +**基于引用计数方案** 基于引用技术的资源管理方案,可以帮助我们实现安全的资源卸载策略,更好的对内存管理,避免资源对象冗余。还有强大的分析器可帮助发现潜在的资源泄漏问题。 -#### 多种模式自由切换 +**多种模式自由切换** 编辑器模拟模式,单机运行模式,联机运行模式。在编辑器模拟模式下,可以不构建资源包来模拟线上环境,在不修改任何代码的情况下,可以自由切换到其它模式。 -#### 强大安全的加载系统 -1. **异步加载和同步加载** 异步加载接口支持协程,Task,委托。支持异步加载和同步加载混合使用。 -2. **边玩边下载** 在加载资源对象的时候,如果资源对象依赖的资源包在本地不存在,会自动从服务器下载到本地,然后再加载资源对象。 -3. **多线程下载** 支持断点续传,自动验证下载文件,自动修复损坏文件。可以自定义下载失败重试次数,下载超时判定时间。 -4. **多功能下载器** 可以按照资源标签列表创建下载器,也可以按照资源对象列表创建下载器。下载器可以设置同时下载文件数的限制,设置下载失败重试次数,多个下载器同时下载不用担心文件重复下载问题,下载器还提供了下载进度以及下载失败异常等常用接口。 +**强大安全的加载系统** -#### 原生格式文件管理 +- **异步加载和同步加载** 异步加载接口支持协程,Task,委托。支持异步加载和同步加载混合使用。 +- **边玩边下载** 在加载资源对象的时候,如果资源对象依赖的资源包在本地不存在,会自动从服务器下载到本地,然后再加载资源对象。 +- **多线程下载** 支持断点续传,自动验证下载文件,自动修复损坏文件。可以自定义下载失败重试次数,下载超时判定时间。 +- **多功能下载器** 可以按照资源标签列表创建下载器,也可以按照资源对象列表创建下载器。下载器可以设置同时下载文件数的限制,设置下载失败重试次数,多个下载器同时下载不用担心文件重复下载问题,下载器还提供了下载进度以及下载失败异常等常用接口。 + +**原生格式文件管理** 无缝衔接资源打包系统,可以很方便的实现原生文件的版本管理和下载。 -#### 灵活多变的版本管理 +**灵活多变的版本管理** 支持线上版本快速回退,支持区分审核版本,测试版本,线上版本,支持灰度更新及测试。 +## 入门教程 +**1. 快速开始** +**2. 全局配置** +**3. 资源收集** +**4. 资源打包** +**5. 资源部署** -# 教程 -#### 加载路径的匹配方式 -````C# -// 不带扩展名的模糊匹配 -YooAssets.LoadAssetAsync("Audio/bgMusic"); - -// 带扩展名的精准匹配 -YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); -```` - -#### 异步加载 -````C# -// 委托加载方式 -void Start() -{ - AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); - handle.Completed += Handle_Completed; -} -void Handle_Completed(AssetOperationHandle handle) -{ - if(handle.AssetObject == null) return; - AudioClip audioClip = handle.AssetObject as AudioClip; -} -```` -````C# -// 协程加载方式 -void Start() -{ - this.StartCoroutine(AsyncLoad()); -} -IEnumerator AsyncLoad() -{ - AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); - yield return handle; - AudioClip audioClip = handle.AssetObject as AudioClip; -} -```` -````C# -// Task加载方式 -async void Start() -{ - await AsyncLoad(); -} -async Task AsyncLoad() -{ - AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); - await handle.Task; - AudioClip audioClip = handle.AssetObject as AudioClip; -} -```` - -#### 资源卸载 -````C# -public void Start() -{ - AssetOperationHandle handle = YooAssets.LoadAssetAsync("Audio/bgMusic.mp3"); - - ... - - // 卸载资源 - handle.Release(); -} -```` \ No newline at end of file +## 代码教程 +**1. 初始化** +**2. 资源更新** +**3. 资源加载**