mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-21 07:50:20 +00:00
feat : instant asset build pipeline
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// InstantAsset 表上下文
|
||||
/// </summary>
|
||||
internal sealed class InstantAssetTableContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化结果
|
||||
/// </summary>
|
||||
public readonly struct InitializeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
public readonly string Error;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化是否成功
|
||||
/// </summary>
|
||||
public bool Succeeded
|
||||
{
|
||||
get { return Error == null; }
|
||||
}
|
||||
|
||||
private InitializeResult(string error)
|
||||
{
|
||||
Error = error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建表示初始化成功的默认结果
|
||||
/// </summary>
|
||||
public static InitializeResult Default()
|
||||
{
|
||||
return new InitializeResult(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建表示初始化失败的结果
|
||||
/// </summary>
|
||||
/// <param name="error">错误信息</param>
|
||||
public static InitializeResult Failure(string error)
|
||||
{
|
||||
return new InitializeResult(error);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly string _rootPath;
|
||||
private readonly string _assetTableName;
|
||||
private readonly string _sceneTableName;
|
||||
|
||||
/// <summary>
|
||||
/// 资源表
|
||||
/// </summary>
|
||||
public InstantAssetTable AssetTable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 场景表
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 如果不包含场景资源,该值为空值。
|
||||
/// </remarks>
|
||||
public InstantAssetTable SceneTable { get; private set; }
|
||||
|
||||
public InstantAssetTableContext(string rootPath, string assetTableName)
|
||||
{
|
||||
_rootPath = rootPath;
|
||||
_assetTableName = assetTableName;
|
||||
_sceneTableName = $"{assetTableName}-scene";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化表上下文
|
||||
/// </summary>
|
||||
/// <returns>初始化结果</returns>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载当前上下文持有的所有表
|
||||
/// </summary>
|
||||
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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5b6f5ba1933ecc43aca5558fef29a05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// InstantAsset 资源包句柄
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UnloadBundle()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
|
||||
{
|
||||
var operation = new IBHLoadAssetOperation(_packageBundle, _assetTable, assetInfo);
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
|
||||
{
|
||||
var operation = new IBHLoadAllAssetsOperation();
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
|
||||
{
|
||||
var operation = new IBHLoadSubAssetsOperation();
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool allowSceneActivation)
|
||||
{
|
||||
var operation = new IBHLoadSceneOperation(_sceneTable, assetInfo, loadSceneParams, allowSceneActivation);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee9ecce87893f2945abc4f58b56a1752
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 全部资源加载操作(InstantBundle不支持)
|
||||
/// </summary>
|
||||
internal sealed class IBHLoadAllAssetsOperation : BHLoadAllAssetsOperation
|
||||
{
|
||||
protected override void InternalStart()
|
||||
{
|
||||
SetError($"{nameof(IBHLoadAllAssetsOperation)} does not support loading all assets.");
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0ac8e1310da5784cbe904b31d9fc8fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,119 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个资源加载操作(InstantBundle)
|
||||
/// </summary>
|
||||
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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 582ff9e5617080c4aa204f8e135f1226
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 场景加载操作(InstantBundle)
|
||||
/// </summary>
|
||||
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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f177d255bd70d3e499548cbfa6a46a26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
#if TUANJIE_1_8_OR_NEWER
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 子资源加载操作(InstantBundle不支持)
|
||||
/// </summary>
|
||||
internal sealed class IBHLoadSubAssetsOperation : BHLoadSubAssetsOperation
|
||||
{
|
||||
protected override void InternalStart()
|
||||
{
|
||||
SetError($"{nameof(IBHLoadSubAssetsOperation)} does not support loading sub-assets.");
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf69bf22c6ce62e4b8d28a5517e0b89d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -35,5 +35,10 @@ namespace YooAsset
|
||||
/// 自定义运行模式
|
||||
/// </summary>
|
||||
CustomPlayMode,
|
||||
|
||||
/// <summary>
|
||||
/// 免构建运行模式
|
||||
/// </summary>
|
||||
DatalessPlayMode,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user