diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs new file mode 100644 index 00000000..b234c96c --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs @@ -0,0 +1,124 @@ +#if TUANJIE_1_8_OR_NEWER + +using UnityEngine; + +namespace YooAsset +{ + /// + /// InstantAsset 表上下文 + /// + internal sealed class InstantAssetTableContext + { + /// + /// 初始化结果 + /// + public readonly struct InitializeResult + { + /// + /// 错误信息 + /// + public readonly string Error; + + /// + /// 初始化是否成功 + /// + public bool Succeeded + { + get { return Error == null; } + } + + private InitializeResult(string error) + { + Error = error; + } + + /// + /// 创建表示初始化成功的默认结果 + /// + public static InitializeResult Default() + { + return new InitializeResult(null); + } + + /// + /// 创建表示初始化失败的结果 + /// + /// 错误信息 + public static InitializeResult Failure(string error) + { + return new InitializeResult(error); + } + } + + private readonly string _rootPath; + private readonly string _assetTableName; + private readonly string _sceneTableName; + + /// + /// 资源表 + /// + public InstantAssetTable AssetTable { get; private set; } + + /// + /// 场景表 + /// + /// + /// 如果不包含场景资源,该值为空值。 + /// + public InstantAssetTable SceneTable { get; private set; } + + public InstantAssetTableContext(string rootPath, string assetTableName) + { + _rootPath = rootPath; + _assetTableName = assetTableName; + _sceneTableName = $"{assetTableName}-scene"; + } + + /// + /// 初始化表上下文 + /// + /// 初始化结果 + public InitializeResult Initialize() + { + InstantAsset.SetInstantAssetRootPath(_rootPath); + + string assetTablePath = PathUtility.Combine(_rootPath, _assetTableName); + AssetTable = InstantAsset.ReadAssetTable(assetTablePath) as InstantAssetTable; + if (AssetTable == null) + { + string error = $"Failed to load InstantAssetTable: '{assetTablePath}'."; + return InitializeResult.Failure(error); + } + + string sceneTablePath = PathUtility.Combine(_rootPath, _sceneTableName); + SceneTable = InstantAsset.ReadAssetTable(sceneTablePath) as InstantAssetTable; + if (SceneTable == null) + { + YooLogger.LogWarning($"InstantAsset scene table not found: '{sceneTablePath}'."); + } + + return InitializeResult.Default(); + } + + /// + /// 卸载当前上下文持有的所有表 + /// + public void Dispose() + { + if (AssetTable != null) + { + string assetTablePath = PathUtility.Combine(_rootPath, _assetTableName); + InstantAsset.UnloadAssetTable(assetTablePath); + AssetTable = null; + } + + if (SceneTable != null) + { + string sceneTablePath = PathUtility.Combine(_rootPath, _sceneTableName); + InstantAsset.UnloadAssetTable(sceneTablePath); + SceneTable = null; + } + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs.meta new file mode 100644 index 00000000..63e8c560 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantAssetTableContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5b6f5ba1933ecc43aca5558fef29a05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs new file mode 100644 index 00000000..ee893c8a --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs @@ -0,0 +1,57 @@ +#if TUANJIE_1_8_OR_NEWER +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace YooAsset +{ + /// + /// InstantAsset 资源包句柄 + /// + internal sealed class InstantBundleHandle : IBundleHandle + { + private readonly PackageBundle _packageBundle; + private readonly InstantAssetTable _assetTable; + private readonly InstantAssetTable _sceneTable; + + public InstantBundleHandle(PackageBundle packageBundle, InstantAssetTable assetTable, InstantAssetTable sceneTable) + { + _packageBundle = packageBundle; + _assetTable = assetTable; + _sceneTable = sceneTable; + } + + /// + public void UnloadBundle() + { + } + + /// + public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) + { + var operation = new IBHLoadAssetOperation(_packageBundle, _assetTable, assetInfo); + return operation; + } + + /// + public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) + { + var operation = new IBHLoadAllAssetsOperation(); + return operation; + } + + /// + public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) + { + var operation = new IBHLoadSubAssetsOperation(); + return operation; + } + + /// + public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool allowSceneActivation) + { + var operation = new IBHLoadSceneOperation(_sceneTable, assetInfo, loadSceneParams, allowSceneActivation); + return operation; + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs.meta new file mode 100644 index 00000000..13f43214 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/InstantBundleHandle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee9ecce87893f2945abc4f58b56a1752 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs new file mode 100644 index 00000000..e4f23f7e --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs @@ -0,0 +1,18 @@ +#if TUANJIE_1_8_OR_NEWER +namespace YooAsset +{ + /// + /// 全部资源加载操作(InstantBundle不支持) + /// + internal sealed class IBHLoadAllAssetsOperation : BHLoadAllAssetsOperation + { + protected override void InternalStart() + { + SetError($"{nameof(IBHLoadAllAssetsOperation)} does not support loading all assets."); + } + protected override void InternalUpdate() + { + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs.meta new file mode 100644 index 00000000..d15be193 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAllAssetsOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0ac8e1310da5784cbe904b31d9fc8fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs new file mode 100644 index 00000000..b9630060 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs @@ -0,0 +1,119 @@ +#if TUANJIE_1_8_OR_NEWER +using UnityEngine; + +namespace YooAsset +{ + /// + /// 单个资源加载操作(InstantBundle) + /// + internal sealed class IBHLoadAssetOperation : BHLoadAssetOperation + { + private enum ESteps + { + None, + CheckAssetTable, + LoadAsset, + CheckResult, + Done, + } + + private readonly PackageBundle _packageBundle; + private readonly InstantAssetTable _assetTable; + private readonly AssetInfo _assetInfo; + private InstantAssetRequest _request; + private ESteps _steps = ESteps.None; + + public IBHLoadAssetOperation(PackageBundle packageBundle, InstantAssetTable assetTable, AssetInfo assetInfo) + { + _packageBundle = packageBundle; + _assetTable = assetTable; + _assetInfo = assetInfo; + } + protected override void InternalStart() + { + _steps = ESteps.CheckAssetTable; + } + protected override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckAssetTable) + { + if (_assetTable == null) + { + _steps = ESteps.Done; + SetError($"{nameof(IBHLoadAssetOperation)} asset table is null, cannot load asset: '{_assetInfo.AssetPath}'."); + YooLogger.LogError(Error); + return; + } + + _steps = ESteps.LoadAsset; + } + + if (_steps == ESteps.LoadAsset) + { + if (IsWaitForCompletion) + { + if (_assetInfo.AssetType == null) + Result = _assetTable.LoadAsset(_assetInfo.AssetPath); + else + Result = _assetTable.LoadAsset(_assetInfo.AssetPath, _assetInfo.AssetType); + } + else + { + if (_assetInfo.AssetType == null) + _request = _assetTable.LoadAssetAsync(_assetInfo.AssetPath); + else + _request = _assetTable.LoadAssetAsync(_assetInfo.AssetPath, _assetInfo.AssetType); + } + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_request != null) + { + // 注意: 异步加载过程中,业务逻辑可能会强制转换为同步加载 + if (IsWaitForCompletion) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.LogWarning("Blocking the main thread while loading an InstantAsset."); + Result = _request.asset; + } + else + { + Progress = _request.progress; + if (_request.isDone == false) + return; + Result = _request.asset; + } + } + + if (Result == null) + { + string error; + if (_assetInfo.AssetType == null) + error = $"Failed to load asset: '{_assetInfo.AssetPath}' AssetType: null InstantBundle: '{_packageBundle.BundleName}'."; + else + error = $"Failed to load asset: '{_assetInfo.AssetPath}' AssetType: {_assetInfo.AssetType} InstantBundle: '{_packageBundle.BundleName}'."; + + _steps = ESteps.Done; + SetError(error); + YooLogger.LogError(Error); + } + else + { + _steps = ESteps.Done; + SetResult(); + } + } + } + protected override void InternalWaitForCompletion() + { + ExecuteBatch(); + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs.meta new file mode 100644 index 00000000..9ab5e956 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadAssetOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 582ff9e5617080c4aa204f8e135f1226 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs new file mode 100644 index 00000000..6734c5ab --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs @@ -0,0 +1,130 @@ +#if TUANJIE_1_8_OR_NEWER +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace YooAsset +{ + /// + /// 场景加载操作(InstantBundle) + /// + internal sealed class IBHLoadSceneOperation : BHLoadSceneOperation + { + private enum ESteps + { + None, + CheckSceneTable, + LoadScene, + CheckResult, + Done, + } + + private readonly InstantAssetTable _sceneTable; + private readonly AssetInfo _assetInfo; + private readonly LoadSceneParameters _loadSceneParams; + private bool _allowSceneActivation; + private AsyncOperation _asyncOperation; + private ESteps _steps = ESteps.None; + + public IBHLoadSceneOperation(InstantAssetTable sceneTable, AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool allowSceneActivation) + { + _sceneTable = sceneTable; + _assetInfo = assetInfo; + _loadSceneParams = loadSceneParams; + _allowSceneActivation = allowSceneActivation; + } + protected override void InternalStart() + { + _steps = ESteps.CheckSceneTable; + } + protected override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckSceneTable) + { + if (_sceneTable == null) + { + _steps = ESteps.Done; + SetError($"{nameof(IBHLoadSceneOperation)} scene table is null, cannot load scene: '{_assetInfo.AssetPath}'."); + YooLogger.LogError(Error); + return; + } + + _steps = ESteps.LoadScene; + } + + if (_steps == ESteps.LoadScene) + { + if (IsWaitForCompletion) + { + _steps = ESteps.Done; + SetError($"{nameof(IBHLoadSceneOperation)} does not support synchronous scene loading."); + YooLogger.LogError(Error); + return; + } + else + { + _asyncOperation = SceneManager.LoadSceneAsync(_assetInfo.AssetPath, _loadSceneParams); + if (_asyncOperation != null) + { + _asyncOperation.allowSceneActivation = _allowSceneActivation; + _asyncOperation.priority = 100; + Result = SceneManager.GetSceneAt(SceneManager.sceneCount - 1); + _steps = ESteps.CheckResult; + } + else + { + _steps = ESteps.Done; + SetError($"Failed to load scene: '{_assetInfo.AssetPath}'."); + YooLogger.LogError(Error); + } + } + } + + if (_steps == ESteps.CheckResult) + { + if (_asyncOperation != null) + { + if (IsWaitForCompletion) + { + YooLogger.LogError("The scene is already loading asynchronously."); + } + else + { + if (_asyncOperation.allowSceneActivation == false) + { + if (_allowSceneActivation) + _asyncOperation.allowSceneActivation = true; + } + + Progress = _asyncOperation.progress; + if (_asyncOperation.isDone == false) + return; + } + } + + if (Result.IsValid()) + { + _steps = ESteps.Done; + SetResult(); + } + else + { + _steps = ESteps.Done; + SetError($"Loaded scene is invalid: '{_assetInfo.AssetPath}'."); + YooLogger.LogError(Error); + } + } + } + protected override void InternalWaitForCompletion() + { + ExecuteOnce(); + } + protected override void InternalAllowSceneActivation() + { + _allowSceneActivation = true; + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs.meta new file mode 100644 index 00000000..40560e36 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSceneOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f177d255bd70d3e499548cbfa6a46a26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs new file mode 100644 index 00000000..df168844 --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs @@ -0,0 +1,18 @@ +#if TUANJIE_1_8_OR_NEWER +namespace YooAsset +{ + /// + /// 子资源加载操作(InstantBundle不支持) + /// + internal sealed class IBHLoadSubAssetsOperation : BHLoadSubAssetsOperation + { + protected override void InternalStart() + { + SetError($"{nameof(IBHLoadSubAssetsOperation)} does not support loading sub-assets."); + } + protected override void InternalUpdate() + { + } + } +} +#endif diff --git a/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs.meta new file mode 100644 index 00000000..d8241cad --- /dev/null +++ b/Assets/YooAsset/Runtime/BundleHandle/Services/InstantBundleHandle/Operations/IBHLoadSubAssetsOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf69bf22c6ce62e4b8d28a5517e0b89d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs index a5ad882f..7e549dae 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/EPlayMode.cs @@ -35,5 +35,10 @@ namespace YooAsset /// 自定义运行模式 /// CustomPlayMode, + + /// + /// 免构建运行模式 + /// + DatalessPlayMode, } } \ No newline at end of file