mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-15 20:20:08 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
469d73d641 | ||
|
|
0d521c68bd | ||
|
|
cd62c1dd9a | ||
|
|
e6422445a6 | ||
|
|
7683746032 | ||
|
|
a25fd19bcc | ||
|
|
6675e8f171 | ||
|
|
c836dce54d | ||
|
|
f3ab8f63e7 | ||
|
|
20d2c517b2 | ||
|
|
d6a2b31d5c | ||
|
|
533f96361a | ||
|
|
09807901c0 | ||
|
|
57ae9aa18c | ||
|
|
08efcaf4c1 | ||
|
|
b221b8121a | ||
|
|
abb75fe858 | ||
|
|
4591d0b5f6 |
@@ -2,6 +2,35 @@
|
||||
|
||||
All notable changes to this package will be documented in this file.
|
||||
|
||||
## [1.0.5] - 2022-04-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复了非主动收集的着色器没有打进统一的着色器资源包的问题。
|
||||
- 修复了单个收集的资源对象没有设置依赖资源列表的问题。
|
||||
- 修复Task异步加载一直等待的问题。
|
||||
|
||||
### Changed
|
||||
|
||||
- 资源打包的过滤文件列表增加cginc格式。
|
||||
- 增加编辑器扩展的支持,第三方实现YooAsset插件。
|
||||
- 优化原生文件加载逻辑,支持离线运行模式和编辑器运行模式。
|
||||
- 优化场景卸载逻辑,在加载新的主场景的时候自动卸载已经加载的所有场景。
|
||||
- 支持演练构建模式,在不生成资源包的情况下快速构建查看结果。
|
||||
- 新增调试信息,出生场景和出生时间。
|
||||
|
||||
## [1.0.4] - 2022-04-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复资源清单附加版本之后引发的一个流程错误。
|
||||
- 修复原生文件拷贝目录不存导致的加载失败。
|
||||
|
||||
### Changed
|
||||
|
||||
- 在编辑器下检测资源路径是否合法并警告。
|
||||
- 完善原生文件异步加载接口。
|
||||
|
||||
## [1.0.3] - 2022-04-14
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -48,6 +48,12 @@ namespace YooAsset.Editor
|
||||
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
|
||||
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
|
||||
|
||||
if (Parameters.DryRunBuild)
|
||||
{
|
||||
opt |= BuildAssetBundleOptions.DryRunBuild;
|
||||
return opt;
|
||||
}
|
||||
|
||||
if (Parameters.CompressOption == ECompressOption.Uncompressed)
|
||||
opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
|
||||
else if (Parameters.CompressOption == ECompressOption.LZ4)
|
||||
@@ -107,7 +113,8 @@ namespace YooAsset.Editor
|
||||
{
|
||||
new TaskPrepare(), //前期准备工作
|
||||
new TaskGetBuildMap(), //获取构建列表
|
||||
new TaskBuilding(), //开始执行构建
|
||||
new TaskBuilding(), //开始执行构建
|
||||
new TaskVerifyBuildResult(), //验证构建结果
|
||||
new TaskEncryption(), //加密资源文件
|
||||
new TaskCreatePatchManifest(), //创建清单文件
|
||||
new TaskCreateReport(), //创建报告文件
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public bool IsCollectAsset { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为着色器资源
|
||||
/// </summary>
|
||||
public bool IsShaderAsset { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 被依赖次数
|
||||
/// </summary>
|
||||
@@ -54,6 +59,12 @@ namespace YooAsset.Editor
|
||||
IsRawAsset = isRawAsset;
|
||||
NotWriteToAssetList = notWriteToAssetList;
|
||||
IsCollectAsset = true;
|
||||
|
||||
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Shader))
|
||||
IsShaderAsset = true;
|
||||
else
|
||||
IsShaderAsset = false;
|
||||
}
|
||||
public BuildAssetInfo(string assetPath)
|
||||
{
|
||||
@@ -61,6 +72,12 @@ namespace YooAsset.Editor
|
||||
IsRawAsset = false;
|
||||
NotWriteToAssetList = true;
|
||||
IsCollectAsset = false;
|
||||
|
||||
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Shader))
|
||||
IsShaderAsset = true;
|
||||
else
|
||||
IsShaderAsset = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -82,7 +99,7 @@ namespace YooAsset.Editor
|
||||
if (string.IsNullOrEmpty(BundleName) == false)
|
||||
throw new System.Exception("Should never get here !");
|
||||
|
||||
BundleName = bundleName;
|
||||
BundleName = bundleName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -99,7 +116,7 @@ namespace YooAsset.Editor
|
||||
/// <summary>
|
||||
/// 添加资源分类标签
|
||||
/// </summary>
|
||||
public void AddAssetTag(string tag)
|
||||
public void AddAssetTag(string tag)
|
||||
{
|
||||
if (AssetTags.Contains(tag) == false)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
if (buildAssetDic.ContainsKey(collectAssetInfo.AssetPath) == false)
|
||||
{
|
||||
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset, collectAssetInfo.NotWriteToAssetList);
|
||||
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset, collectAssetInfo.NotWriteToAssetList);
|
||||
buildAssetInfo.SetBundleName(collectAssetInfo.BundleName);
|
||||
buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
|
||||
buildAssetDic.Add(collectAssetInfo.AssetPath, buildAssetInfo);
|
||||
@@ -78,6 +78,13 @@ namespace YooAsset.Editor
|
||||
var buildAssetInfo = pair.Value;
|
||||
if (buildAssetInfo.IsCollectAsset)
|
||||
continue;
|
||||
|
||||
if (AssetBundleGrouperSettingData.Setting.AutoCollectShaders)
|
||||
{
|
||||
if (buildAssetInfo.IsShaderAsset)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buildAssetInfo.DependCount == 0)
|
||||
removeList.Add(buildAssetInfo);
|
||||
}
|
||||
@@ -93,9 +100,17 @@ namespace YooAsset.Editor
|
||||
var buildAssetInfo = pair.Value;
|
||||
if (buildAssetInfo.BundleNameIsValid() == false)
|
||||
{
|
||||
string bundleName = defaultPackRule.GetBundleName(new PackRuleData(buildAssetInfo.AssetPath));
|
||||
bundleName = AssetBundleCollector.RevisedBundleName(bundleName, false);
|
||||
buildAssetInfo.SetBundleName(bundleName);
|
||||
string shaderBundleName = AssetBundleCollector.CollectShaderBundleName(buildAssetInfo.AssetPath);
|
||||
if (string.IsNullOrEmpty(shaderBundleName) == false)
|
||||
{
|
||||
buildAssetInfo.SetBundleName(shaderBundleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
string bundleName = defaultPackRule.GetBundleName(new PackRuleData(buildAssetInfo.AssetPath));
|
||||
bundleName = AssetBundleCollector.CorrectBundleName(bundleName, false);
|
||||
buildAssetInfo.SetBundleName(bundleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace YooAsset.Editor
|
||||
public IEncryptionServices EncryptionServices;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 演练构建模式
|
||||
/// </summary>
|
||||
public bool DryRunBuild;
|
||||
|
||||
/// <summary>
|
||||
/// 强制重新构建整个项目,如果为FALSE则是增量打包
|
||||
/// </summary>
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace YooAsset.Editor
|
||||
public string EncryptionServicesClassName;
|
||||
|
||||
// 构建参数
|
||||
public bool DryRunBuild;
|
||||
public bool ForceRebuild;
|
||||
public string BuildinTags;
|
||||
public ECompressOption CompressOption;
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace YooAsset.Editor
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Build task {task.GetType().Name} failed : {e}");
|
||||
Debug.LogError($"Build task {task.GetType().Name} failed !");
|
||||
Debug.LogError($"Detail error : {e}");
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -31,164 +31,29 @@ namespace YooAsset.Editor
|
||||
context.SetContextObject(unityManifestContext);
|
||||
|
||||
// 拷贝原生文件
|
||||
if (buildParametersContext.Parameters.DryRunBuild == false)
|
||||
{
|
||||
CopyRawBundle(buildMapContext, buildParametersContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝原生文件
|
||||
/// </summary>
|
||||
private void CopyRawBundle(BuildMapContext buildMapContext, AssetBundleBuilder.BuildParametersContext buildParametersContext)
|
||||
{
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.IsRawFile)
|
||||
{
|
||||
string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
foreach(var buildAsset in bundleInfo.BuildinAssets)
|
||||
foreach (var buildAsset in bundleInfo.BuildinAssets)
|
||||
{
|
||||
if(buildAsset.IsRawAsset)
|
||||
if (buildAsset.IsRawAsset)
|
||||
EditorTools.CopyFile(buildAsset.AssetPath, dest, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 验证构建结果
|
||||
if (buildParametersContext.Parameters.VerifyBuildingResult)
|
||||
{
|
||||
VerifyingBuildingResult(context, unityManifest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证构建结果
|
||||
/// </summary>
|
||||
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
|
||||
{
|
||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||
string[] buildedBundles = unityManifest.GetAllAssetBundles();
|
||||
|
||||
// 1. 过滤掉原生Bundle
|
||||
List<BuildBundleInfo> expectBundles = new List<BuildBundleInfo>(buildedBundles.Length);
|
||||
foreach(var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.IsRawFile == false)
|
||||
expectBundles.Add(bundleInfo);
|
||||
}
|
||||
|
||||
// 2. 验证数量
|
||||
if (buildedBundles.Length != expectBundles.Count)
|
||||
{
|
||||
Debug.LogWarning($"构建过程中可能存在无效的资源,导致和预期构建的Bundle数量不一致!");
|
||||
}
|
||||
|
||||
// 3. 正向验证Bundle
|
||||
foreach (var bundleName in buildedBundles)
|
||||
{
|
||||
if (buildMapContext.IsContainsBundle(bundleName) == false)
|
||||
{
|
||||
throw new Exception($"Should never get here !");
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 反向验证Bundle
|
||||
bool isPass = true;
|
||||
foreach (var expectBundle in expectBundles)
|
||||
{
|
||||
bool isMatch = false;
|
||||
foreach (var buildedBundle in buildedBundles)
|
||||
{
|
||||
if (buildedBundle == expectBundle.BundleName)
|
||||
{
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isMatch == false)
|
||||
{
|
||||
isPass = false;
|
||||
Debug.LogWarning($"没有找到预期构建的Bundle文件 : {expectBundle.BundleName}");
|
||||
}
|
||||
}
|
||||
if(isPass == false)
|
||||
{
|
||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||
}
|
||||
|
||||
// 5. 验证Asset
|
||||
int progressValue = 0;
|
||||
foreach (var buildedBundle in buildedBundles)
|
||||
{
|
||||
string filePath = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
|
||||
string[] allBuildinAssetPaths = GetAssetBundleAllAssets(filePath);
|
||||
string[] expectBuildinAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
|
||||
if (expectBuildinAssetPaths.Length != allBuildinAssetPaths.Length)
|
||||
{
|
||||
Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var buildinAssetPath in allBuildinAssetPaths)
|
||||
{
|
||||
var guid = AssetDatabase.AssetPathToGUID(buildinAssetPath);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Debug.LogWarning($"无效的资源路径,请检查路径是否带有特殊符号或中文:{buildinAssetPath}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isMatch = false;
|
||||
foreach (var exceptBuildAssetPath in expectBuildinAssetPaths)
|
||||
{
|
||||
var guidExcept = AssetDatabase.AssetPathToGUID(exceptBuildAssetPath);
|
||||
if (guid == guidExcept)
|
||||
{
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isMatch == false)
|
||||
{
|
||||
Debug.LogWarning($"在构建的Bundle文件里发现了没有匹配的资源对象:{buildinAssetPath}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
|
||||
}
|
||||
EditorTools.ClearProgressBar();
|
||||
if (isPass == false)
|
||||
{
|
||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||
}
|
||||
|
||||
// 卸载所有加载的Bundle
|
||||
Debug.Log("构建结果验证成功!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析.manifest文件并获取资源列表
|
||||
/// </summary>
|
||||
private string[] GetAssetBundleAllAssets(string filePath)
|
||||
{
|
||||
string manifestFilePath = $"{filePath}.manifest";
|
||||
List<string> assetLines = new List<string>();
|
||||
using (StreamReader reader = File.OpenText(manifestFilePath))
|
||||
{
|
||||
string content;
|
||||
bool findTarget = false;
|
||||
while (null != (content = reader.ReadLine()))
|
||||
{
|
||||
if (content.StartsWith("Dependencies:"))
|
||||
break;
|
||||
if (findTarget == false && content.StartsWith("Assets:"))
|
||||
findTarget = true;
|
||||
if (findTarget)
|
||||
{
|
||||
if (content.StartsWith("- "))
|
||||
{
|
||||
string assetPath = content.TrimStart("- ".ToCharArray());
|
||||
assetLines.Add(assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return assetLines.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
// 注意:我们只有在强制重建的时候才会拷贝
|
||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
if (buildParameters.Parameters.ForceRebuild)
|
||||
if (buildParameters.Parameters.DryRunBuild == false && buildParameters.Parameters.ForceRebuild)
|
||||
{
|
||||
// 清空流目录
|
||||
AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
|
||||
|
||||
@@ -62,14 +62,14 @@ namespace YooAsset.Editor
|
||||
// 内置标记列表
|
||||
List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
|
||||
|
||||
bool dryRunBuild = buildParameters.Parameters.DryRunBuild;
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
var bundleName = bundleInfo.BundleName;
|
||||
string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
|
||||
string hash = HashUtility.FileMD5(filePath);
|
||||
string crc32 = HashUtility.FileCRC32(filePath);
|
||||
long size = FileUtility.GetFileSize(filePath);
|
||||
int version = buildParameters.Parameters.BuildVersion;
|
||||
string hash = GetFileHash(filePath, dryRunBuild);
|
||||
string crc32 = GetFileCRC(filePath, dryRunBuild);
|
||||
long size = GetFileSize(filePath, dryRunBuild);
|
||||
string[] tags = buildMapContext.GetAssetTags(bundleName);
|
||||
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
|
||||
bool isBuildin = IsBuildinBundle(tags, buildinTags);
|
||||
@@ -101,6 +101,27 @@ namespace YooAsset.Editor
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private string GetFileHash(string filePath, bool dryRunBuild)
|
||||
{
|
||||
if (dryRunBuild)
|
||||
return "00000000000000000000000000000000"; //32位
|
||||
else
|
||||
return HashUtility.FileMD5(filePath);
|
||||
}
|
||||
private string GetFileCRC(string filePath, bool dryRunBuild)
|
||||
{
|
||||
if (dryRunBuild)
|
||||
return "00000000"; //8位
|
||||
else
|
||||
return HashUtility.FileCRC32(filePath);
|
||||
}
|
||||
private long GetFileSize(string filePath, bool dryRunBuild)
|
||||
{
|
||||
if (dryRunBuild)
|
||||
return 0;
|
||||
else
|
||||
return FileUtility.GetFileSize(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源列表
|
||||
|
||||
@@ -11,7 +11,10 @@ namespace YooAsset.Editor
|
||||
void IBuildTask.Run(BuildContext context)
|
||||
{
|
||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
CopyPatchFiles(buildParameters);
|
||||
if (buildParameters.Parameters.DryRunBuild == false)
|
||||
{
|
||||
CopyPatchFiles(buildParameters);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -35,8 +35,9 @@ namespace YooAsset.Editor
|
||||
buildReport.Summary.ShadersBundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
|
||||
buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ?
|
||||
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
|
||||
|
||||
|
||||
// 构建参数
|
||||
buildReport.Summary.DryRunBuild = buildParameters.Parameters.DryRunBuild;
|
||||
buildReport.Summary.ForceRebuild = buildParameters.Parameters.ForceRebuild;
|
||||
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
|
||||
buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption;
|
||||
|
||||
@@ -26,9 +26,18 @@ namespace YooAsset.Editor
|
||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||
|
||||
EncryptionContext encryptionContext = new EncryptionContext();
|
||||
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
|
||||
context.SetContextObject(encryptionContext);
|
||||
if (buildParameters.Parameters.DryRunBuild)
|
||||
{
|
||||
EncryptionContext encryptionContext = new EncryptionContext();
|
||||
encryptionContext.EncryptList = new List<string>();
|
||||
context.SetContextObject(encryptionContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncryptionContext encryptionContext = new EncryptionContext();
|
||||
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
|
||||
context.SetContextObject(encryptionContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class TaskVerifyBuildResult : IBuildTask
|
||||
{
|
||||
void IBuildTask.Run(BuildContext context)
|
||||
{
|
||||
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
var unityManifestContext = context.GetContextObject<TaskBuilding.UnityManifestContext>();
|
||||
|
||||
// 验证构建结果
|
||||
if (buildParametersContext.Parameters.VerifyBuildingResult)
|
||||
{
|
||||
VerifyingBuildingResult(context, unityManifestContext.UnityManifest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证构建结果
|
||||
/// </summary>
|
||||
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
|
||||
{
|
||||
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
|
||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||
string[] buildedBundles = unityManifest.GetAllAssetBundles();
|
||||
|
||||
// 1. 过滤掉原生Bundle
|
||||
List<BuildBundleInfo> expectBundles = new List<BuildBundleInfo>(buildedBundles.Length);
|
||||
foreach(var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.IsRawFile == false)
|
||||
expectBundles.Add(bundleInfo);
|
||||
}
|
||||
|
||||
// 2. 验证数量
|
||||
if (buildedBundles.Length != expectBundles.Count)
|
||||
{
|
||||
Debug.LogWarning($"构建过程中可能存在无效的资源,导致和预期构建的Bundle数量不一致!");
|
||||
}
|
||||
|
||||
// 3. 正向验证Bundle
|
||||
foreach (var bundleName in buildedBundles)
|
||||
{
|
||||
if (buildMapContext.IsContainsBundle(bundleName) == false)
|
||||
{
|
||||
throw new Exception($"Should never get here !");
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 反向验证Bundle
|
||||
bool isPass = true;
|
||||
foreach (var expectBundle in expectBundles)
|
||||
{
|
||||
bool isMatch = false;
|
||||
foreach (var buildedBundle in buildedBundles)
|
||||
{
|
||||
if (buildedBundle == expectBundle.BundleName)
|
||||
{
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isMatch == false)
|
||||
{
|
||||
isPass = false;
|
||||
Debug.LogWarning($"没有找到预期构建的Bundle文件 : {expectBundle.BundleName}");
|
||||
}
|
||||
}
|
||||
if(isPass == false)
|
||||
{
|
||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||
}
|
||||
|
||||
// 5. 验证Asset
|
||||
if(buildParameters.Parameters.DryRunBuild == false)
|
||||
{
|
||||
int progressValue = 0;
|
||||
foreach (var buildedBundle in buildedBundles)
|
||||
{
|
||||
string filePath = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
|
||||
string[] allBuildinAssetPaths = GetAssetBundleAllAssets(filePath);
|
||||
string[] expectBuildinAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
|
||||
if (expectBuildinAssetPaths.Length != allBuildinAssetPaths.Length)
|
||||
{
|
||||
Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var buildinAssetPath in allBuildinAssetPaths)
|
||||
{
|
||||
var guid = AssetDatabase.AssetPathToGUID(buildinAssetPath);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Debug.LogWarning($"无效的资源路径,请检查路径是否带有特殊符号或中文:{buildinAssetPath}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isMatch = false;
|
||||
foreach (var exceptBuildAssetPath in expectBuildinAssetPaths)
|
||||
{
|
||||
var guidExcept = AssetDatabase.AssetPathToGUID(exceptBuildAssetPath);
|
||||
if (guid == guidExcept)
|
||||
{
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isMatch == false)
|
||||
{
|
||||
Debug.LogWarning($"在构建的Bundle文件里发现了没有匹配的资源对象:{buildinAssetPath}");
|
||||
isPass = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
|
||||
}
|
||||
EditorTools.ClearProgressBar();
|
||||
if (isPass == false)
|
||||
{
|
||||
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||
}
|
||||
}
|
||||
|
||||
// 卸载所有加载的Bundle
|
||||
Debug.Log("构建结果验证成功!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析.manifest文件并获取资源列表
|
||||
/// </summary>
|
||||
private string[] GetAssetBundleAllAssets(string filePath)
|
||||
{
|
||||
string manifestFilePath = $"{filePath}.manifest";
|
||||
List<string> assetLines = new List<string>();
|
||||
using (StreamReader reader = File.OpenText(manifestFilePath))
|
||||
{
|
||||
string content;
|
||||
bool findTarget = false;
|
||||
while (null != (content = reader.ReadLine()))
|
||||
{
|
||||
if (content.StartsWith("Dependencies:"))
|
||||
break;
|
||||
if (findTarget == false && content.StartsWith("Assets:"))
|
||||
findTarget = true;
|
||||
if (findTarget)
|
||||
{
|
||||
if (content.StartsWith("- "))
|
||||
{
|
||||
string assetPath = content.TrimStart("- ".ToCharArray());
|
||||
assetLines.Add(assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return assetLines.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b883ac0c3c25e8143847a9326e2961cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -114,7 +114,7 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 100;
|
||||
label.style.width = 150;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
@@ -124,6 +124,26 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 150;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
{
|
||||
var label = new Label();
|
||||
label.name = "Label4";
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 100;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
{
|
||||
var label = new Label();
|
||||
label.name = "Label5";
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 120;
|
||||
element.Add(label);
|
||||
}
|
||||
@@ -139,9 +159,17 @@ namespace YooAsset.Editor
|
||||
var label1 = element.Q<Label>("Label1");
|
||||
label1.text = providerInfo.AssetPath;
|
||||
|
||||
// Ref Count
|
||||
// Spawn Scene
|
||||
var label2 = element.Q<Label>("Label2");
|
||||
label2.text = providerInfo.RefCount.ToString();
|
||||
label2.text = providerInfo.SpawnScene;
|
||||
|
||||
// Spawn Time
|
||||
var label3 = element.Q<Label>("Label3");
|
||||
label3.text = providerInfo.SpawnTime;
|
||||
|
||||
// Ref Count
|
||||
var label4 = element.Q<Label>("Label4");
|
||||
label4.text = providerInfo.RefCount.ToString();
|
||||
|
||||
// Status
|
||||
StyleColor textColor;
|
||||
@@ -149,9 +177,9 @@ namespace YooAsset.Editor
|
||||
textColor = new StyleColor(Color.yellow);
|
||||
else
|
||||
textColor = label1.style.color;
|
||||
var label3 = element.Q<Label>("Label3");
|
||||
label3.text = providerInfo.Status.ToString();
|
||||
label3.style.color = textColor;
|
||||
var label5 = element.Q<Label>("Label5");
|
||||
label5.text = providerInfo.Status.ToString();
|
||||
label5.style.color = textColor;
|
||||
}
|
||||
private void AssetListView_onSelectionChange(IEnumerable<object> objs)
|
||||
{
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Asset Path" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="TopBar3" style="width: 120px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Spawn Scene" display-tooltip-when-elided="true" name="TopBar2" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Spawn Time" display-tooltip-when-elided="true" name="TopBar3" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="TopBar4" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="TopBar5" style="width: 120px; -unity-text-align: middle-left;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -65,14 +65,14 @@ namespace YooAsset.Editor
|
||||
Dictionary<string, DebugBundleInfo> result = new Dictionary<string, DebugBundleInfo>(debugReport.ProviderInfos.Count);
|
||||
foreach (var providerInfo in debugReport.ProviderInfos)
|
||||
{
|
||||
foreach(var bundleInfo in providerInfo.BundleInfos)
|
||||
foreach (var bundleInfo in providerInfo.BundleInfos)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchKeyWord) == false)
|
||||
{
|
||||
if (bundleInfo.BundleName.Contains(searchKeyWord) == false)
|
||||
continue;
|
||||
}
|
||||
if(result.ContainsKey(bundleInfo.BundleName) == false)
|
||||
if (result.ContainsKey(bundleInfo.BundleName) == false)
|
||||
result.Add(bundleInfo.BundleName, bundleInfo);
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace YooAsset.Editor
|
||||
_root.RemoveFromHierarchy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 顶部列表相关
|
||||
private VisualElement MakeAssetListViewItem()
|
||||
{
|
||||
@@ -188,7 +188,7 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 100;
|
||||
label.style.width = 150;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
@@ -198,10 +198,30 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 150;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
{
|
||||
var label = new Label();
|
||||
label.name = "Label4";
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 100;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
{
|
||||
var label = new Label();
|
||||
label.name = "Label5";
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 120;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
private void BindIncludeListViewItem(VisualElement element, int index)
|
||||
@@ -213,29 +233,37 @@ namespace YooAsset.Editor
|
||||
var label1 = element.Q<Label>("Label1");
|
||||
label1.text = providerInfo.AssetPath;
|
||||
|
||||
// Ref Count
|
||||
// Spawn Scene
|
||||
var label2 = element.Q<Label>("Label2");
|
||||
label2.text = providerInfo.RefCount.ToString();
|
||||
label2.text = providerInfo.SpawnScene;
|
||||
|
||||
// Spawn Time
|
||||
var label3 = element.Q<Label>("Label3");
|
||||
label3.text = providerInfo.SpawnTime;
|
||||
|
||||
// Ref Count
|
||||
var label4 = element.Q<Label>("Label4");
|
||||
label4.text = providerInfo.RefCount.ToString();
|
||||
|
||||
// Status
|
||||
var label3 = element.Q<Label>("Label3");
|
||||
label3.text = providerInfo.Status.ToString();
|
||||
var label5 = element.Q<Label>("Label5");
|
||||
label5.text = providerInfo.Status.ToString();
|
||||
}
|
||||
private void FillUsingListView(string bundleName)
|
||||
{
|
||||
_usingListView.Clear();
|
||||
_usingListView.ClearSelection();
|
||||
|
||||
List<DebugProviderInfo> source = new List<DebugProviderInfo>();
|
||||
foreach(var providerInfo in _debugReport.ProviderInfos)
|
||||
List<DebugProviderInfo> source = new List<DebugProviderInfo>();
|
||||
foreach (var providerInfo in _debugReport.ProviderInfos)
|
||||
{
|
||||
foreach(var bundleInfo in providerInfo.BundleInfos)
|
||||
foreach (var bundleInfo in providerInfo.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.BundleName == bundleName)
|
||||
{
|
||||
source.Add(providerInfo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_usingListView.itemsSource = source;
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Using Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="BottomBar3" style="width: 100px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="BottomBar4" style="width: 120px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Spawn Scene" display-tooltip-when-elided="true" name="BottomBar2" style="width: 150px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Spawn Time" display-tooltip-when-elided="true" name="BottomBar3" style="width: 150px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Ref Count" display-tooltip-when-elided="true" name="BottomBar4" style="width: 100px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Status" display-tooltip-when-elided="true" name="BottomBar5" style="width: 120px; -unity-text-align: middle-left;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace YooAsset.Editor
|
||||
string bundleName = GetBundleName(grouper, assetPath, isRawAsset);
|
||||
List<string> assetTags = GetAssetTags(grouper);
|
||||
var collectAssetInfo = new CollectAssetInfo(bundleName, assetPath, assetTags, isRawAsset, NotWriteToAssetList);
|
||||
collectAssetInfo.DependAssets = GetAllDependencies(assetPath);
|
||||
result.Add(assetPath, collectAssetInfo);
|
||||
}
|
||||
else
|
||||
@@ -120,7 +121,7 @@ namespace YooAsset.Editor
|
||||
return false;
|
||||
|
||||
string ext = System.IO.Path.GetExtension(assetPath);
|
||||
if (ext == "" || ext == ".dll" || ext == ".cs" || ext == ".js" || ext == ".boo" || ext == ".meta")
|
||||
if (ext == "" || ext == ".dll" || ext == ".cs" || ext == ".js" || ext == ".boo" || ext == ".meta" || ext == ".cginc")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -141,22 +142,15 @@ namespace YooAsset.Editor
|
||||
}
|
||||
private string GetBundleName(AssetBundleGrouper grouper, string assetPath, bool isRawAsset)
|
||||
{
|
||||
// 如果收集全路径着色器
|
||||
if (AssetBundleGrouperSettingData.Setting.AutoCollectShaders)
|
||||
{
|
||||
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Shader))
|
||||
{
|
||||
string bundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
|
||||
return RevisedBundleName(bundleName, false);
|
||||
}
|
||||
}
|
||||
string shaderBundleName = CollectShaderBundleName(assetPath);
|
||||
if (string.IsNullOrEmpty(shaderBundleName) == false)
|
||||
return shaderBundleName;
|
||||
|
||||
// 根据规则设置获取资源包名称
|
||||
{
|
||||
IPackRule packRuleInstance = AssetBundleGrouperSettingData.GetPackRuleInstance(PackRuleName);
|
||||
string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, grouper.GrouperName));
|
||||
return RevisedBundleName(bundleName, isRawAsset);
|
||||
return CorrectBundleName(bundleName, isRawAsset);
|
||||
}
|
||||
}
|
||||
private List<string> GetAssetTags(AssetBundleGrouper grouper)
|
||||
@@ -182,11 +176,28 @@ namespace YooAsset.Editor
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 收集着色器的资源包名称
|
||||
/// </summary>
|
||||
public static string CollectShaderBundleName(string assetPath)
|
||||
{
|
||||
// 如果自动收集所有的着色器
|
||||
if (AssetBundleGrouperSettingData.Setting.AutoCollectShaders)
|
||||
{
|
||||
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Shader))
|
||||
{
|
||||
string bundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
|
||||
return CorrectBundleName(bundleName, false);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修正资源包名
|
||||
/// 修正资源包名称
|
||||
/// </summary>
|
||||
public static string RevisedBundleName(string bundleName, bool isRawBundle)
|
||||
public static string CorrectBundleName(string bundleName, bool isRawBundle)
|
||||
{
|
||||
if (isRawBundle)
|
||||
{
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 250;
|
||||
label.style.width = 280;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Depend Bundles" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="BottomBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="BottomBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 250;
|
||||
label.style.width = 280;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace YooAsset.Editor
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
label.style.marginLeft = 3f;
|
||||
//label.style.flexGrow = 1f;
|
||||
label.style.width = 250;
|
||||
label.style.width = 280;
|
||||
element.Add(label);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Bundle Name" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" style="flex-grow: 1;" />
|
||||
@@ -13,7 +13,7 @@
|
||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Include Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="BottomBar2" style="width: 100px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar3" style="width: 250px; -unity-text-align: middle-left;" />
|
||||
<uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar3" style="width: 280px; -unity-text-align: middle-left;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="BottomListView" item-height="18" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace YooAsset.Editor
|
||||
|
||||
_items.Add(new ItemWrapper(string.Empty, string.Empty));
|
||||
_items.Add(new ItemWrapper("构建参数", string.Empty));
|
||||
_items.Add(new ItemWrapper("DryRunBuild", $"{buildReport.Summary.DryRunBuild}"));
|
||||
_items.Add(new ItemWrapper("ForceRebuild", $"{buildReport.Summary.ForceRebuild}"));
|
||||
_items.Add(new ItemWrapper("BuildinTags", $"{buildReport.Summary.BuildinTags}"));
|
||||
_items.Add(new ItemWrapper("CompressOption", $"{buildReport.Summary.CompressOption}"));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
@@ -10,7 +11,8 @@ namespace YooAsset
|
||||
{
|
||||
private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
|
||||
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
|
||||
|
||||
private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
|
||||
|
||||
/// <summary>
|
||||
/// 在编辑器下模拟运行
|
||||
/// </summary>
|
||||
@@ -127,23 +129,21 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载原生文件
|
||||
/// </summary>
|
||||
public static RawFileOperation LoadRawFileAsync(string assetPath, string savePath)
|
||||
{
|
||||
string bundleName = BundleServices.GetBundleName(assetPath);
|
||||
BundleInfo bundleInfo = BundleServices.GetBundleInfo(bundleName);
|
||||
RawFileOperation operation = new RawFileOperation(bundleInfo, savePath);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载场景
|
||||
/// </summary>
|
||||
public static SceneOperationHandle LoadSceneAsync(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
|
||||
{
|
||||
// 注意:场景句柄永远保持唯一
|
||||
if (_sceneHandles.ContainsKey(scenePath))
|
||||
return _sceneHandles[scenePath];
|
||||
|
||||
// 如果加载的是主场景,则卸载所有缓存的场景
|
||||
if (sceneMode == LoadSceneMode.Single)
|
||||
{
|
||||
UnloadAllScene();
|
||||
}
|
||||
|
||||
ProviderBase provider = TryGetProvider(scenePath);
|
||||
if (provider == null)
|
||||
{
|
||||
@@ -151,9 +151,13 @@ namespace YooAsset
|
||||
provider = new DatabaseSceneProvider(scenePath, sceneMode, activateOnLoad, priority);
|
||||
else
|
||||
provider = new BundledSceneProvider(scenePath, sceneMode, activateOnLoad, priority);
|
||||
provider.InitSpawnDebugInfo();
|
||||
_providers.Add(provider);
|
||||
}
|
||||
return provider.CreateHandle() as SceneOperationHandle;
|
||||
|
||||
var handle = provider.CreateHandle() as SceneOperationHandle;
|
||||
_sceneHandles.Add(scenePath, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -168,6 +172,7 @@ namespace YooAsset
|
||||
provider = new DatabaseAssetProvider(assetPath, assetType);
|
||||
else
|
||||
provider = new BundledAssetProvider(assetPath, assetType);
|
||||
provider.InitSpawnDebugInfo();
|
||||
_providers.Add(provider);
|
||||
}
|
||||
return provider.CreateHandle() as AssetOperationHandle;
|
||||
@@ -185,12 +190,55 @@ namespace YooAsset
|
||||
provider = new DatabaseSubAssetsProvider(assetPath, assetType);
|
||||
else
|
||||
provider = new BundledSubAssetsProvider(assetPath, assetType);
|
||||
provider.InitSpawnDebugInfo();
|
||||
_providers.Add(provider);
|
||||
}
|
||||
return provider.CreateHandle() as SubAssetsOperationHandle;
|
||||
}
|
||||
|
||||
|
||||
internal static void UnloadSubScene(ProviderBase provider)
|
||||
{
|
||||
string scenePath = provider.AssetPath;
|
||||
if (_sceneHandles.ContainsKey(scenePath) == false)
|
||||
throw new Exception("Should never get here !");
|
||||
|
||||
// 释放子场景句柄
|
||||
_sceneHandles[scenePath].ReleaseInternal();
|
||||
_sceneHandles.Remove(scenePath);
|
||||
|
||||
// 卸载未被使用的资源(包括场景)
|
||||
AssetSystem.UnloadUnusedAssets();
|
||||
|
||||
// 检验子场景是否销毁
|
||||
if (provider.IsDestroyed == false)
|
||||
{
|
||||
throw new Exception("Should never get here !");
|
||||
}
|
||||
}
|
||||
internal static void UnloadAllScene()
|
||||
{
|
||||
// 释放所有场景句柄
|
||||
foreach (var valuePair in _sceneHandles)
|
||||
{
|
||||
valuePair.Value.ReleaseInternal();
|
||||
}
|
||||
_sceneHandles.Clear();
|
||||
|
||||
// 卸载未被使用的资源(包括场景)
|
||||
AssetSystem.UnloadUnusedAssets();
|
||||
|
||||
// 检验所有场景是否销毁
|
||||
foreach (var provider in _providers)
|
||||
{
|
||||
if (provider.IsSceneProvider())
|
||||
{
|
||||
if (provider.IsDestroyed == false)
|
||||
throw new Exception("Should never get here !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static AssetBundleLoaderBase CreateOwnerAssetBundleLoader(string assetPath)
|
||||
{
|
||||
string bundleName = BundleServices.GetBundleName(assetPath);
|
||||
@@ -266,6 +314,7 @@ namespace YooAsset
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
||||
#region 调试专属方法
|
||||
internal static void GetDebugReport(DebugReport report)
|
||||
{
|
||||
@@ -277,6 +326,8 @@ namespace YooAsset
|
||||
{
|
||||
DebugProviderInfo providerInfo = new DebugProviderInfo();
|
||||
providerInfo.AssetPath = provider.AssetPath;
|
||||
providerInfo.SpawnScene = provider.SpawnScene;
|
||||
providerInfo.SpawnTime = provider.SpawnTime;
|
||||
providerInfo.RefCount = provider.RefCount;
|
||||
providerInfo.Status = provider.Status;
|
||||
providerInfo.BundleInfos.Clear();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public class AssetOperationHandle : OperationHandleBase
|
||||
public sealed class AssetOperationHandle : OperationHandleBase
|
||||
{
|
||||
private System.Action<AssetOperationHandle> _callback;
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@ namespace YooAsset
|
||||
{
|
||||
public abstract class OperationHandleBase : IEnumerator
|
||||
{
|
||||
private readonly string _cachedAssetPath;
|
||||
internal ProviderBase _provider { private set; get; }
|
||||
|
||||
|
||||
internal OperationHandleBase(ProviderBase provider)
|
||||
{
|
||||
_provider = provider;
|
||||
_cachedAssetPath = provider.AssetPath;
|
||||
}
|
||||
internal abstract void InvokeCallback();
|
||||
|
||||
@@ -63,7 +65,18 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
return _provider != null && _provider.IsDestroyed == false;
|
||||
if (_provider != null && _provider.IsDestroyed == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_provider == null)
|
||||
YooLogger.Warning($"Operation handle is released : {_cachedAssetPath}");
|
||||
else if (_provider.IsDestroyed)
|
||||
YooLogger.Warning($"Provider is destroyed : {_cachedAssetPath}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +95,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步操作任务
|
||||
/// </summary>
|
||||
public System.Threading.Tasks.Task<object> Task
|
||||
public System.Threading.Tasks.Task Task
|
||||
{
|
||||
get { return _provider.Task; }
|
||||
}
|
||||
|
||||
@@ -69,10 +69,35 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步卸载场景
|
||||
/// 是否为主场景
|
||||
/// </summary>
|
||||
public bool IsMainScene()
|
||||
{
|
||||
if (IsValid == false)
|
||||
return false;
|
||||
|
||||
if (_provider is DatabaseSceneProvider)
|
||||
{
|
||||
var temp = _provider as DatabaseSceneProvider;
|
||||
return temp.SceneMode == LoadSceneMode.Single;
|
||||
}
|
||||
else if (_provider is BundledSceneProvider)
|
||||
{
|
||||
var temp = _provider as BundledSceneProvider;
|
||||
return temp.SceneMode == LoadSceneMode.Single;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步卸载子场景
|
||||
/// </summary>
|
||||
public UnloadSceneOperation UnloadAsync()
|
||||
{
|
||||
// 如果句柄无效
|
||||
if (IsValid == false)
|
||||
{
|
||||
string error = $"{nameof(SceneOperationHandle)} is invalid.";
|
||||
@@ -81,54 +106,23 @@ namespace YooAsset
|
||||
return operation;
|
||||
}
|
||||
|
||||
ProviderBase provider = _provider;
|
||||
|
||||
// 释放场景句柄
|
||||
ReleaseInternal();
|
||||
|
||||
// 卸载未被使用的资源(包括场景)
|
||||
AssetSystem.UnloadUnusedAssets();
|
||||
|
||||
// 返回场景卸载异步操作类
|
||||
if (provider.IsDestroyed == false)
|
||||
// 如果是主场景
|
||||
if (IsMainScene())
|
||||
{
|
||||
YooLogger.Warning($"Scene can not unload. The provider not destroyed : {provider.AssetPath}");
|
||||
var operation = new UnloadSceneOperation();
|
||||
string error = $"Cannot unload main scene. Use {nameof(YooAssets.LoadSceneAsync)} method to change the main scene !";
|
||||
YooLogger.Error(error);
|
||||
var operation = new UnloadSceneOperation(error);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsAdditiveScene(provider))
|
||||
{
|
||||
var operation = new UnloadSceneOperation(provider.SceneObject);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
var operation = new UnloadSceneOperation();
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAdditiveScene(ProviderBase provider)
|
||||
{
|
||||
if (provider is DatabaseSceneProvider)
|
||||
// 卸载子场景
|
||||
Scene sceneObject = SceneObject;
|
||||
AssetSystem.UnloadSubScene(_provider);
|
||||
{
|
||||
var temp = provider as DatabaseSceneProvider;
|
||||
return temp.SceneMode == LoadSceneMode.Additive;
|
||||
}
|
||||
else if (provider is BundledSceneProvider)
|
||||
{
|
||||
var temp = provider as BundledSceneProvider;
|
||||
return temp.SceneMode == LoadSceneMode.Additive;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
var operation = new UnloadSceneOperation(sceneObject);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public class SubAssetsOperationHandle : OperationHandleBase
|
||||
public sealed class SubAssetsOperationHandle : OperationHandleBase
|
||||
{
|
||||
private System.Action<SubAssetsOperationHandle> _callback;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private string _fileLoadPath;
|
||||
private bool _isWaitForAsyncComplete = false;
|
||||
private bool _isShowWaitForAsyncError = false;
|
||||
private DownloaderBase _downloader;
|
||||
@@ -38,18 +39,32 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.None)
|
||||
{
|
||||
// 检测加载地址是否为空
|
||||
if (string.IsNullOrEmpty(BundleFileInfo.LocalPath))
|
||||
if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(BundleFileInfo.RemoteMainURL))
|
||||
_steps = ESteps.LoadFile;
|
||||
else
|
||||
if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
_fileLoadPath = BundleFileInfo.GetCacheLoadPath();
|
||||
}
|
||||
else if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.LoadFile;
|
||||
_fileLoadPath = BundleFileInfo.GetStreamingLoadPath();
|
||||
}
|
||||
else if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.LoadFile;
|
||||
_fileLoadPath = BundleFileInfo.GetCacheLoadPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(BundleFileInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 从服务器下载
|
||||
@@ -83,9 +98,9 @@ namespace YooAsset
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
|
||||
if (System.IO.File.Exists(BundleFileInfo.LocalPath) == false)
|
||||
if (System.IO.File.Exists(_fileLoadPath) == false)
|
||||
{
|
||||
YooLogger.Warning($"Not found assetBundle file : {BundleFileInfo.LocalPath}");
|
||||
YooLogger.Warning($"Not found assetBundle file : {_fileLoadPath}");
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
return;
|
||||
@@ -96,20 +111,20 @@ namespace YooAsset
|
||||
if (BundleFileInfo.IsEncrypted)
|
||||
{
|
||||
if (AssetSystem.DecryptionServices == null)
|
||||
throw new Exception($"{nameof(AssetBundleFileLoader)} need IDecryptServices : {BundleFileInfo.BundleName}");
|
||||
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {BundleFileInfo.BundleName}");
|
||||
|
||||
ulong offset = AssetSystem.DecryptionServices.GetFileOffset(BundleFileInfo);
|
||||
if (_isWaitForAsyncComplete)
|
||||
CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath, 0, offset);
|
||||
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
|
||||
else
|
||||
_cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath, 0, offset);
|
||||
_cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
CacheBundle = AssetBundle.LoadFromFile(BundleFileInfo.LocalPath);
|
||||
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath);
|
||||
else
|
||||
_cacheRequest = AssetBundle.LoadFromFileAsync(BundleFileInfo.LocalPath);
|
||||
_cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
|
||||
}
|
||||
_steps = ESteps.CheckFile;
|
||||
}
|
||||
|
||||
@@ -37,19 +37,22 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.None)
|
||||
{
|
||||
// 检测加载地址是否为空
|
||||
if (string.IsNullOrEmpty(BundleFileInfo.LocalPath))
|
||||
if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(BundleFileInfo.RemoteMainURL))
|
||||
_webURL = BundleFileInfo.LocalPath;
|
||||
if (BundleFileInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.LoadFile;
|
||||
_webURL = BundleFileInfo.GetStreamingLoadPath();
|
||||
}
|
||||
else
|
||||
_webURL = BundleFileInfo.RemoteMainURL;
|
||||
_steps = ESteps.LoadFile;
|
||||
{
|
||||
throw new System.NotImplementedException(BundleFileInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 从服务器或缓存中获取AssetBundle文件
|
||||
|
||||
@@ -48,12 +48,15 @@ namespace YooAsset
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{nameof(AssetOperationHandle)} is invalid.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (_handle.AssetObject == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{nameof(AssetOperationHandle.AssetObject)} is null.";
|
||||
return;
|
||||
}
|
||||
|
||||
if(_setPositionRotation)
|
||||
|
||||
@@ -2,39 +2,70 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public class RawFileOperation : AsyncOperationBase
|
||||
/// <summary>
|
||||
/// 原生文件操作
|
||||
/// </summary>
|
||||
public abstract class RawFileOperation : AsyncOperationBase
|
||||
{
|
||||
protected readonly BundleInfo _bundleInfo;
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的拷贝路径
|
||||
/// </summary>
|
||||
public string CopyPath { private set; get; }
|
||||
|
||||
|
||||
internal RawFileOperation(BundleInfo bundleInfo, string copyPath)
|
||||
{
|
||||
_bundleInfo = bundleInfo;
|
||||
CopyPath = copyPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public abstract string GetCachePath();
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的二进制数据
|
||||
/// </summary>
|
||||
public byte[] GetFileData()
|
||||
{
|
||||
string filePath = GetCachePath();
|
||||
if (File.Exists(filePath) == false)
|
||||
return null;
|
||||
return File.ReadAllBytes(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的文本数据
|
||||
/// </summary>
|
||||
public string GetFileText()
|
||||
{
|
||||
string filePath = GetCachePath();
|
||||
if (File.Exists(filePath) == false)
|
||||
return string.Empty;
|
||||
return File.ReadAllText(filePath, System.Text.Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class EditorPlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
DownloadFromWeb,
|
||||
CheckDownloadFromWeb,
|
||||
CheckFile,
|
||||
DownloadFromApk,
|
||||
CheckDownloadFromApk,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly BundleInfo _bundleInfo;
|
||||
private readonly string _savePath;
|
||||
private ESteps _steps = ESteps.None;
|
||||
private DownloaderBase _downloader;
|
||||
private UnityWebFileRequester _fileRequester;
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的存储路径
|
||||
/// </summary>
|
||||
public string SavePath
|
||||
internal EditorPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
get { return _savePath; }
|
||||
}
|
||||
|
||||
|
||||
internal RawFileOperation(BundleInfo bundleInfo, string savePath)
|
||||
{
|
||||
_bundleInfo = bundleInfo;
|
||||
_savePath = savePath;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -48,19 +79,250 @@ namespace YooAsset
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
// 检测加载地址是否为空
|
||||
if (string.IsNullOrEmpty(_bundleInfo.LocalPath))
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
return; // 模拟实现异步操作
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "Local path is null or empty.";
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_bundleInfo.RemoteMainURL))
|
||||
_steps = ESteps.CheckFile;
|
||||
// 如果原生文件已经存在,则将其删除
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return _bundleInfo.BundleName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离线模式的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class OfflinePlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
DownloadFromApk,
|
||||
CheckDownloadFromApk,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private UnityWebFileRequester _fileRequester;
|
||||
|
||||
public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.DownloadFromApk;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 从APK拷贝文件
|
||||
if (_steps == ESteps.DownloadFromApk)
|
||||
{
|
||||
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
|
||||
_fileRequester = new UnityWebFileRequester();
|
||||
_fileRequester.SendRequest(downloadURL, GetCachePath());
|
||||
_steps = ESteps.CheckDownloadFromApk;
|
||||
}
|
||||
|
||||
// 3. 检测APK拷贝文件结果
|
||||
if (_steps == ESteps.CheckDownloadFromApk)
|
||||
{
|
||||
if (_fileRequester.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_fileRequester.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _fileRequester.GetError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
_fileRequester.Dispose();
|
||||
}
|
||||
|
||||
// 4. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果原生文件已经存在,则验证其完整性
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
bool result = DownloadSystem.CheckContentIntegrity(CopyPath, _bundleInfo.SizeBytes, _bundleInfo.CRC);
|
||||
if (result)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return _bundleInfo.GetCacheLoadPath();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络模式的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class HostPlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
DownloadFromWeb,
|
||||
CheckDownloadFromWeb,
|
||||
DownloadFromApk,
|
||||
CheckDownloadFromApk,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private DownloaderBase _downloader;
|
||||
private UnityWebFileRequester _fileRequester;
|
||||
|
||||
internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.DownloadFromWeb;
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.DownloadFromApk;
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 从服务器下载
|
||||
@@ -85,65 +347,20 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
// 注意:当文件更新之后,需要删除旧文件
|
||||
if (File.Exists(_savePath))
|
||||
File.Delete(_savePath);
|
||||
_steps = ESteps.CheckFile;
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 检测文件
|
||||
if (_steps == ESteps.CheckFile)
|
||||
{
|
||||
// 注意:如果原生文件已经存在,则验证其完整性
|
||||
if (File.Exists(_savePath))
|
||||
{
|
||||
bool result = DownloadSystem.CheckContentIntegrity(_savePath, _bundleInfo.SizeBytes, _bundleInfo.CRC);
|
||||
if (result)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(_savePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (_bundleInfo.IsBuildinJarFile())
|
||||
{
|
||||
_steps = ESteps.DownloadFromApk;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Copy(_bundleInfo.LocalPath, _savePath, true);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.ToString();
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 从APK拷贝文件
|
||||
// 4. 从APK拷贝文件
|
||||
if (_steps == ESteps.DownloadFromApk)
|
||||
{
|
||||
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.LocalPath);
|
||||
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
|
||||
_fileRequester = new UnityWebFileRequester();
|
||||
_fileRequester.SendRequest(downloadURL, _savePath);
|
||||
_fileRequester.SendRequest(downloadURL, GetCachePath());
|
||||
_steps = ESteps.CheckDownloadFromApk;
|
||||
}
|
||||
|
||||
// 6. 检测APK拷贝文件结果
|
||||
// 5. 检测APK拷贝文件结果
|
||||
if (_steps == ESteps.CheckDownloadFromApk)
|
||||
{
|
||||
if (_fileRequester.IsDone() == false)
|
||||
@@ -157,32 +374,62 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
_fileRequester.Dispose();
|
||||
}
|
||||
|
||||
// 6. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果原生文件已经存在,则验证其完整性
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
bool result = DownloadSystem.CheckContentIntegrity(CopyPath, _bundleInfo.SizeBytes, _bundleInfo.CRC);
|
||||
if (result)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
|
||||
_fileRequester.Dispose();
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的二进制数据
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public byte[] GetFileData()
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (File.Exists(_savePath) == false)
|
||||
return null;
|
||||
return File.ReadAllBytes(_savePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的文本数据
|
||||
/// </summary>
|
||||
public string GetFileText()
|
||||
{
|
||||
if (File.Exists(_savePath) == false)
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return File.ReadAllText(_savePath, System.Text.Encoding.UTF8);
|
||||
return _bundleInfo.GetCacheLoadPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ namespace YooAsset
|
||||
{
|
||||
Normal,
|
||||
Error,
|
||||
Skip,
|
||||
}
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -40,10 +39,6 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
internal UnloadSceneOperation()
|
||||
{
|
||||
_flag = EFlag.Skip;
|
||||
}
|
||||
internal UnloadSceneOperation(string error)
|
||||
{
|
||||
_flag = EFlag.Error;
|
||||
@@ -60,11 +55,6 @@ namespace YooAsset
|
||||
{
|
||||
_steps = ESteps.UnLoad;
|
||||
}
|
||||
else if (_flag == EFlag.Skip)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else if (_flag == EFlag.Error)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -197,31 +199,22 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步操作任务
|
||||
/// </summary>
|
||||
public System.Threading.Tasks.Task<object> Task
|
||||
public Task Task
|
||||
{
|
||||
get
|
||||
{
|
||||
var handle = WaitHandle;
|
||||
return System.Threading.Tasks.Task.Factory.StartNew(o =>
|
||||
if (_taskCompletionSource == null)
|
||||
{
|
||||
handle.WaitOne();
|
||||
return AssetObject as object;
|
||||
}, this);
|
||||
_taskCompletionSource = new TaskCompletionSource<object>();
|
||||
if (IsDone)
|
||||
_taskCompletionSource.SetResult(null);
|
||||
}
|
||||
return _taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
#region 异步编程相关
|
||||
private System.Threading.EventWaitHandle _waitHandle;
|
||||
private System.Threading.WaitHandle WaitHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_waitHandle == null)
|
||||
_waitHandle = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset);
|
||||
_waitHandle.Reset();
|
||||
return _waitHandle;
|
||||
}
|
||||
}
|
||||
private TaskCompletionSource<object> _taskCompletionSource;
|
||||
protected void InvokeCompletion()
|
||||
{
|
||||
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
|
||||
@@ -233,7 +226,35 @@ namespace YooAsset
|
||||
hande.InvokeCallback();
|
||||
}
|
||||
}
|
||||
_waitHandle?.Set();
|
||||
|
||||
if (_taskCompletionSource != null)
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 调试信息相关
|
||||
/// <summary>
|
||||
/// 出生的场景
|
||||
/// </summary>
|
||||
public string SpawnScene = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 出生的时间
|
||||
/// </summary>
|
||||
public string SpawnTime = string.Empty;
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public void InitSpawnDebugInfo()
|
||||
{
|
||||
SpawnScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; ;
|
||||
SpawnTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup);
|
||||
}
|
||||
private string SpawnTimeToString(float spawnTime)
|
||||
{
|
||||
float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f);
|
||||
float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f);
|
||||
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
|
||||
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -11,6 +11,16 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public string AssetPath { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源出生的场景
|
||||
/// </summary>
|
||||
public string SpawnScene { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源出生的时间
|
||||
/// </summary>
|
||||
public string SpawnTime { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace YooAsset
|
||||
// 创建新的下载器
|
||||
{
|
||||
YooLogger.Log($"Beginning to download file : {bundleInfo.BundleName} URL : {bundleInfo.RemoteMainURL}");
|
||||
FileUtility.CreateFileDirectory(bundleInfo.LocalPath);
|
||||
FileUtility.CreateFileDirectory(bundleInfo.GetCacheLoadPath());
|
||||
DownloaderBase newDownloader;
|
||||
if (bundleInfo.SizeBytes >= _breakpointResumeFileSize)
|
||||
newDownloader = new HttpDownloader(bundleInfo);
|
||||
@@ -146,7 +146,7 @@ namespace YooAsset
|
||||
// 验证文件完整性
|
||||
public static bool CheckContentIntegrity(BundleInfo bundleInfo)
|
||||
{
|
||||
return CheckContentIntegrity(bundleInfo.LocalPath, bundleInfo.SizeBytes, bundleInfo.CRC);
|
||||
return CheckContentIntegrity(bundleInfo.GetCacheLoadPath(), bundleInfo.SizeBytes, bundleInfo.CRC);
|
||||
}
|
||||
public static bool CheckContentIntegrity(PatchBundle patchBundle)
|
||||
{
|
||||
|
||||
@@ -50,9 +50,6 @@ namespace YooAsset
|
||||
}
|
||||
public void SendRequest(int failedTryAgain, int timeout)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_bundleInfo.LocalPath))
|
||||
throw new System.ArgumentNullException();
|
||||
|
||||
if (_steps == ESteps.None)
|
||||
{
|
||||
_failedTryAgain = failedTryAgain;
|
||||
@@ -62,7 +59,7 @@ namespace YooAsset
|
||||
}
|
||||
public abstract void Update();
|
||||
public abstract void Abort();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络请求地址
|
||||
/// </summary>
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace YooAsset
|
||||
|
||||
_requestURL = GetRequestURL();
|
||||
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_bundleInfo.LocalPath);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_bundleInfo.GetCacheLoadPath());
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
@@ -97,8 +97,9 @@ namespace YooAsset
|
||||
{
|
||||
ReportError();
|
||||
|
||||
if (File.Exists(_bundleInfo.LocalPath))
|
||||
File.Delete(_bundleInfo.LocalPath);
|
||||
string cacheFilePath = _bundleInfo.GetCacheLoadPath();
|
||||
if (File.Exists(cacheFilePath))
|
||||
File.Delete(cacheFilePath);
|
||||
|
||||
// 失败后重新尝试
|
||||
if (_failedTryAgain > 0)
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace YooAsset
|
||||
|
||||
_requestURL = GetRequestURL();
|
||||
_threadDownloader = new ThreadDownloader();
|
||||
_threadDownloader.Run(_requestURL, _bundleInfo.LocalPath, _bundleInfo.Hash, _bundleInfo.CRC, _bundleInfo.SizeBytes, _timeout);
|
||||
_threadDownloader.Run(_requestURL, _bundleInfo.GetCacheLoadPath(), _bundleInfo.Hash, _bundleInfo.CRC, _bundleInfo.SizeBytes, _timeout);
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,25 @@ namespace YooAsset
|
||||
{
|
||||
public class BundleInfo
|
||||
{
|
||||
internal enum ELoadMode
|
||||
{
|
||||
None,
|
||||
LoadFromStreaming,
|
||||
LoadFromCache,
|
||||
LoadFromRemote,
|
||||
}
|
||||
|
||||
private readonly PatchBundle _patchBundle;
|
||||
|
||||
internal readonly ELoadMode LoadMode;
|
||||
|
||||
private string _streamingPath;
|
||||
private string _cachePath;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包名称
|
||||
/// </summary>
|
||||
public string BundleName { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 本地存储的路径
|
||||
/// </summary>
|
||||
public string LocalPath { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 远端下载地址
|
||||
/// </summary>
|
||||
@@ -96,30 +103,57 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取流文件夹的加载路径
|
||||
/// </summary>
|
||||
public string GetStreamingLoadPath()
|
||||
{
|
||||
if (_patchBundle == null)
|
||||
return string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(_streamingPath))
|
||||
_streamingPath = PathHelper.MakeStreamingLoadPath(_patchBundle.Hash);
|
||||
return _streamingPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取缓存文件夹的加载路径
|
||||
/// </summary>
|
||||
public string GetCacheLoadPath()
|
||||
{
|
||||
if (_patchBundle == null)
|
||||
return string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(_cachePath))
|
||||
_cachePath = SandboxHelper.MakeSandboxCacheFilePath(_patchBundle.Hash);
|
||||
return _cachePath;
|
||||
}
|
||||
|
||||
|
||||
private BundleInfo()
|
||||
{
|
||||
}
|
||||
internal BundleInfo(PatchBundle patchBundle, string localPath, string mainURL, string fallbackURL)
|
||||
internal BundleInfo(PatchBundle patchBundle, ELoadMode loadMode, string mainURL, string fallbackURL)
|
||||
{
|
||||
_patchBundle = patchBundle;
|
||||
LoadMode = loadMode;
|
||||
BundleName = patchBundle.BundleName;
|
||||
LocalPath = localPath;
|
||||
RemoteMainURL = mainURL;
|
||||
RemoteFallbackURL = fallbackURL;
|
||||
}
|
||||
internal BundleInfo(PatchBundle patchBundle, string localPath)
|
||||
internal BundleInfo(PatchBundle patchBundle, ELoadMode loadMode)
|
||||
{
|
||||
_patchBundle = patchBundle;
|
||||
LoadMode = loadMode;
|
||||
BundleName = patchBundle.BundleName;
|
||||
LocalPath = localPath;
|
||||
RemoteMainURL = string.Empty;
|
||||
RemoteFallbackURL = string.Empty;
|
||||
}
|
||||
internal BundleInfo(string bundleName, string localPath)
|
||||
internal BundleInfo(string bundleName)
|
||||
{
|
||||
_patchBundle = null;
|
||||
LoadMode = ELoadMode.None;
|
||||
BundleName = bundleName;
|
||||
LocalPath = localPath;
|
||||
RemoteMainURL = string.Empty;
|
||||
RemoteFallbackURL = string.Empty;
|
||||
}
|
||||
@@ -127,9 +161,9 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 是否为JAR包内文件
|
||||
/// </summary>
|
||||
public bool IsBuildinJarFile()
|
||||
public static bool IsBuildinJarFile(string streamingPath)
|
||||
{
|
||||
return LocalPath.StartsWith("jar:");
|
||||
return streamingPath.StartsWith("jar:");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
@@ -15,7 +14,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的初始化操作
|
||||
/// </summary>
|
||||
internal class EditorModeInitializationOperation : InitializationOperation
|
||||
internal sealed class EditorPlayModeInitializationOperation : InitializationOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -29,7 +28,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 离线模式的初始化操作
|
||||
/// </summary>
|
||||
internal class OfflinePlayModeInitializationOperation : InitializationOperation
|
||||
internal sealed class OfflinePlayModeInitializationOperation : InitializationOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -81,7 +80,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 网络模式的初始化操作
|
||||
/// </summary>
|
||||
internal class HostPlayModeInitializationOperation : InitializationOperation
|
||||
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的更新清单操作
|
||||
/// </summary>
|
||||
internal class EditorModeUpdateManifestOperation : UpdateManifestOperation
|
||||
internal sealed class EditorPlayModeUpdateManifestOperation : UpdateManifestOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 离线模式的更新清单操作
|
||||
/// </summary>
|
||||
internal class OfflinePlayModeUpdateManifestOperation : UpdateManifestOperation
|
||||
internal sealed class OfflinePlayModeUpdateManifestOperation : UpdateManifestOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 网络模式的更新清单操作
|
||||
/// </summary>
|
||||
internal class HostPlayModeUpdateManifestOperation : UpdateManifestOperation
|
||||
internal sealed class HostPlayModeUpdateManifestOperation : UpdateManifestOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -113,6 +113,7 @@ namespace YooAsset
|
||||
if (cachedManifestHash == webManifestHash)
|
||||
{
|
||||
YooLogger.Log($"Patch manifest file hash is not change : {webManifestHash}");
|
||||
LoadSandboxPatchManifest(_updateResourceVersion);
|
||||
_steps = ESteps.InitPrepareCache;
|
||||
}
|
||||
else
|
||||
@@ -140,7 +141,7 @@ namespace YooAsset
|
||||
|
||||
// Check error
|
||||
if (_downloaderManifest.HasError())
|
||||
{
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _downloaderManifest.GetError();
|
||||
@@ -211,6 +212,17 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载沙盒内的补丁清单
|
||||
/// </summary>
|
||||
private void LoadSandboxPatchManifest(int updateResourceVersion)
|
||||
{
|
||||
YooLogger.Log("Load sandbox patch manifest file.");
|
||||
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
|
||||
string jsonData = File.ReadAllText(filePath);
|
||||
_impl.LocalPatchManifest = PatchManifest.Deserialize(jsonData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取沙盒内补丁清单文件的哈希值
|
||||
/// 注意:如果沙盒内补丁清单文件不存在,返回空字符串
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -19,7 +17,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的更新静态版本操作
|
||||
/// </summary>
|
||||
internal class EditorModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
internal sealed class EditorPlayModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -33,7 +31,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 离线模式的更新静态版本操作
|
||||
/// </summary>
|
||||
internal class OfflinePlayModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
internal sealed class OfflinePlayModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
@@ -47,7 +45,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 网络模式的更新静态版本操作
|
||||
/// </summary>
|
||||
internal class HostPlayModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
internal sealed class HostPlayModeUpdateStaticVersionOperation : UpdateStaticVersionOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public InitializationOperation InitializeAsync()
|
||||
{
|
||||
var operation = new EditorModeInitializationOperation();
|
||||
var operation = new EditorPlayModeInitializationOperation();
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace YooAsset
|
||||
BundleInfo IBundleServices.GetBundleInfo(string bundleName)
|
||||
{
|
||||
YooLogger.Warning($"Editor play mode can not get bundle info.");
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName, bundleName);
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName);
|
||||
return bundleInfo;
|
||||
}
|
||||
string IBundleServices.GetBundleName(string assetPath)
|
||||
|
||||
@@ -196,10 +196,9 @@ namespace YooAsset
|
||||
private BundleInfo ConvertToDownloadInfo(PatchBundle patchBundle)
|
||||
{
|
||||
// 注意:资源版本号只用于确定下载路径
|
||||
string sandboxPath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash);
|
||||
string remoteMainURL = GetPatchDownloadMainURL(patchBundle.Hash);
|
||||
string remoteFallbackURL = GetPatchDownloadFallbackURL(patchBundle.Hash);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, sandboxPath, remoteMainURL, remoteFallbackURL);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL);
|
||||
return bundleInfo;
|
||||
}
|
||||
|
||||
@@ -207,36 +206,34 @@ namespace YooAsset
|
||||
BundleInfo IBundleServices.GetBundleInfo(string bundleName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
return new BundleInfo(string.Empty, string.Empty);
|
||||
return new BundleInfo(string.Empty);
|
||||
|
||||
if (LocalPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle patchBundle))
|
||||
{
|
||||
// 查询沙盒资源
|
||||
if (DownloadSystem.ContainsVerifyFile(patchBundle.Hash))
|
||||
{
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache);
|
||||
return bundleInfo;
|
||||
}
|
||||
|
||||
// 查询APP资源
|
||||
if (AppPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle appPatchBundle))
|
||||
{
|
||||
if (appPatchBundle.IsBuildin && appPatchBundle.Hash == patchBundle.Hash)
|
||||
{
|
||||
string appLoadPath = PathHelper.MakeStreamingLoadPath(appPatchBundle.Hash);
|
||||
BundleInfo bundleInfo = new BundleInfo(appPatchBundle, appLoadPath);
|
||||
BundleInfo bundleInfo = new BundleInfo(appPatchBundle, BundleInfo.ELoadMode.LoadFromStreaming);
|
||||
return bundleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// 查询沙盒资源
|
||||
if (DownloadSystem.ContainsVerifyFile(patchBundle.Hash))
|
||||
{
|
||||
string sandboxLoadPath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, sandboxLoadPath);
|
||||
return bundleInfo;
|
||||
}
|
||||
|
||||
// 从服务端下载
|
||||
return ConvertToDownloadInfo(patchBundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Not found bundle in patch manifest : {bundleName}");
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName, string.Empty);
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName);
|
||||
return bundleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,18 +42,17 @@ namespace YooAsset
|
||||
BundleInfo IBundleServices.GetBundleInfo(string bundleName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
return new BundleInfo(string.Empty, string.Empty);
|
||||
return new BundleInfo(string.Empty);
|
||||
|
||||
if (AppPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle patchBundle))
|
||||
{
|
||||
string localPath = PathHelper.MakeStreamingLoadPath(patchBundle.Hash);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, localPath);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming);
|
||||
return bundleInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Not found bundle in patch manifest : {bundleName}");
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName, string.Empty);
|
||||
BundleInfo bundleInfo = new BundleInfo(bundleName);
|
||||
return bundleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("YooAsset.Editor")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Editor")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.EditorExtend")]
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -13,6 +14,10 @@ namespace YooAsset
|
||||
}
|
||||
public string ConvertLocationToAssetPath(YooAssets.EPlayMode playMode, string location)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
CheckLocation(location);
|
||||
#endif
|
||||
|
||||
if (playMode == YooAssets.EPlayMode.EditorPlayMode)
|
||||
{
|
||||
string filePath = CombineAssetPath(_resourceRoot, location);
|
||||
@@ -73,5 +78,28 @@ namespace YooAsset
|
||||
throw new System.NotImplementedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void CheckLocation(string location)
|
||||
{
|
||||
if (string.IsNullOrEmpty(location))
|
||||
{
|
||||
Debug.LogError("location param is null or empty!");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检查路径末尾是否有空格
|
||||
int index = location.LastIndexOf(" ");
|
||||
if (index != -1)
|
||||
{
|
||||
if (location.Length == index + 1)
|
||||
Debug.LogWarning($"Found blank character in location : \"{location}\"");
|
||||
}
|
||||
|
||||
if (location.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
|
||||
Debug.LogWarning($"Found illegal character in location : \"{location}\"");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -150,6 +150,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public static List<BundleInfo> GetUnpackListByTags(PatchManifest appPatchManifest, string[] tags)
|
||||
{
|
||||
// 注意:离线运行模式也依赖下面逻辑,所以判断沙盒内文件是否存在不能通过缓存系统去验证。
|
||||
List<PatchBundle> downloadList = new List<PatchBundle>(1000);
|
||||
foreach (var patchBundle in appPatchManifest.BundleList)
|
||||
{
|
||||
@@ -162,19 +163,11 @@ namespace YooAsset
|
||||
if (patchBundle.IsBuildin == false)
|
||||
continue;
|
||||
|
||||
// 如果是纯内置资源
|
||||
if (patchBundle.IsPureBuildin())
|
||||
// 查询DLC资源
|
||||
if (patchBundle.HasTag(tags))
|
||||
{
|
||||
downloadList.Add(patchBundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 查询DLC资源
|
||||
if (patchBundle.HasTag(tags))
|
||||
{
|
||||
downloadList.Add(patchBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ConvertToUnpackList(downloadList);
|
||||
@@ -191,9 +184,10 @@ namespace YooAsset
|
||||
}
|
||||
private static BundleInfo ConvertToUnpackInfo(PatchBundle patchBundle)
|
||||
{
|
||||
string sandboxPath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash);
|
||||
string streamingLoadPath = PathHelper.MakeStreamingLoadPath(patchBundle.Hash);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, sandboxPath, streamingLoadPath, streamingLoadPath);
|
||||
// 注意:我们把流加载路径指定为远端下载地址
|
||||
string streamingPath = PathHelper.MakeStreamingLoadPath(patchBundle.Hash);
|
||||
streamingPath = PathHelper.ConvertToWWWPath(streamingPath);
|
||||
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromRemote, streamingPath, streamingPath);
|
||||
return bundleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,12 +219,11 @@ namespace YooAsset
|
||||
/// 向网络端请求静态资源版本号
|
||||
/// </summary>
|
||||
/// <param name="timeout">超时时间(默认值:60秒)</param>
|
||||
/// <returns></returns>
|
||||
public static UpdateStaticVersionOperation UpdateStaticVersionAsync(int timeout = 60)
|
||||
{
|
||||
if (_playMode == EPlayMode.EditorPlayMode)
|
||||
{
|
||||
var operation = new EditorModeUpdateStaticVersionOperation();
|
||||
var operation = new EditorPlayModeUpdateStaticVersionOperation();
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
@@ -255,7 +254,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_playMode == EPlayMode.EditorPlayMode)
|
||||
{
|
||||
var operation = new EditorModeUpdateManifestOperation();
|
||||
var operation = new EditorPlayModeUpdateManifestOperation();
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
@@ -364,10 +363,40 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步加载原生文件
|
||||
/// </summary>
|
||||
public static RawFileOperation LoadRawFileAsync(string location, string savePath)
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="copyPath">拷贝路径</param>
|
||||
public static RawFileOperation LoadRawFileAsync(string location, string copyPath = null)
|
||||
{
|
||||
string assetPath = _locationServices.ConvertLocationToAssetPath(_playMode, location);
|
||||
return AssetSystem.LoadRawFileAsync(assetPath, savePath);
|
||||
if (_playMode == EPlayMode.EditorPlayMode)
|
||||
{
|
||||
BundleInfo bundleInfo = new BundleInfo(assetPath);
|
||||
RawFileOperation operation = new EditorPlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
IBundleServices bundleServices = _offlinePlayModeImpl;
|
||||
string bundleName = bundleServices.GetBundleName(assetPath);
|
||||
BundleInfo bundleInfo = bundleServices.GetBundleInfo(bundleName);
|
||||
RawFileOperation operation = new OfflinePlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
IBundleServices bundleServices = _hostPlayModeImpl;
|
||||
string bundleName = bundleServices.GetBundleName(assetPath);
|
||||
BundleInfo bundleInfo = bundleServices.GetBundleInfo(bundleName);
|
||||
RawFileOperation operation = new HostPlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.ProcessOperaiton(operation);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +404,7 @@ namespace YooAsset
|
||||
/// 同步加载资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">资源类型</typeparam>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public static AssetOperationHandle LoadAssetSync<TObject>(string location) where TObject : class
|
||||
{
|
||||
return LoadAssetInternal(location, typeof(TObject), true);
|
||||
@@ -384,7 +413,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 同步加载资源对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="type">资源类型</param>
|
||||
public static AssetOperationHandle LoadAssetSync(string location, System.Type type)
|
||||
{
|
||||
@@ -395,7 +424,7 @@ namespace YooAsset
|
||||
/// 同步加载子资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">资源类型</typeparam>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public static SubAssetsOperationHandle LoadSubAssetsSync<TObject>(string location)
|
||||
{
|
||||
return LoadSubAssetsInternal(location, typeof(TObject), true);
|
||||
@@ -404,7 +433,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 同步加载子资源对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="type">子对象类型</param>
|
||||
public static SubAssetsOperationHandle LoadSubAssetsSync(string location, System.Type type)
|
||||
{
|
||||
@@ -416,7 +445,7 @@ namespace YooAsset
|
||||
/// 异步加载资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">资源类型</typeparam>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public static AssetOperationHandle LoadAssetAsync<TObject>(string location)
|
||||
{
|
||||
return LoadAssetInternal(location, typeof(TObject), false);
|
||||
@@ -425,7 +454,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步加载资源对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="type">资源类型</param>
|
||||
public static AssetOperationHandle LoadAssetAsync(string location, System.Type type)
|
||||
{
|
||||
@@ -436,7 +465,7 @@ namespace YooAsset
|
||||
/// 异步加载子资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">资源类型</typeparam>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public static SubAssetsOperationHandle LoadSubAssetsAsync<TObject>(string location)
|
||||
{
|
||||
return LoadSubAssetsInternal(location, typeof(TObject), false);
|
||||
@@ -445,7 +474,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步加载子资源对象
|
||||
/// </summary>
|
||||
/// <param name="location">资源对象相对路径</param>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="type">子对象类型</param>
|
||||
public static SubAssetsOperationHandle LoadSubAssetsAsync(string location, System.Type type)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "com.tuyoogame.yooasset",
|
||||
"displayName": "YooAsset",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.5",
|
||||
"unity": "2019.4",
|
||||
"description": "unity3d resources management system",
|
||||
"author": {
|
||||
|
||||
Reference in New Issue
Block a user