Files
Fishing2/Assets/Scripts/NBC/Asset/Runtime/Asset/Loaders/SceneLoaderFromBundle.cs
2025-05-10 12:49:47 +08:00

143 lines
3.8 KiB
C#

using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace NBC.Asset
{
internal class SceneLoaderFromBundle : ISceneLoader
{
public static ISceneLoader CreateInstance()
{
return new SceneLoaderFromBundle();
}
private enum Steps
{
LoadDependency,
LoadScene,
}
private Dependency _dependency;
private AssetInfo _assetInfo;
private Steps _steps = Steps.LoadDependency;
private SceneProvider _provider;
private bool _isWaitForAsyncComplete;
private AsyncOperation _asyncOperation;
public void Start(SceneProvider provider)
{
_provider = provider;
var newAsset = true;
if (_assetInfo == null)
{
_assetInfo = provider.AssetInfo;
}
else
{
if (_assetInfo.GUID == provider.AssetInfo.GUID)
{
newAsset = false;
}
else
{
_assetInfo = provider.AssetInfo;
}
}
if (newAsset || _dependency == null)
{
_dependency = Dependency.GetAssetDependency(_assetInfo);
_dependency.Retain();
}
_steps = Steps.LoadDependency;
}
public void Update()
{
if (_steps == Steps.LoadDependency)
{
if (_isWaitForAsyncComplete)
{
_dependency.WaitForAsyncComplete();
}
else if (!_dependency.IsDone) return;
if (!_dependency.IsSucceed)
{
Debug.LogError("error");
SetStatus("dependency fail");
}
var provider = _dependency.GetMainBundledProvider();
if (provider != null && provider.AssetBundle != null)
{
var scenePath = Path.GetFileNameWithoutExtension(_assetInfo.Path);
if (_isWaitForAsyncComplete)
{
SceneManager.LoadScene(scenePath, _provider.SceneMode);
SetStatus();
}
else
{
_asyncOperation = SceneManager.LoadSceneAsync(scenePath, _provider.SceneMode);
_asyncOperation.allowSceneActivation = true;
_steps = Steps.LoadScene;
}
}
else
{
//失败,后续补全失败逻辑
Debug.LogError("error1");
SetStatus("error");
}
}
else if (_steps == Steps.LoadScene)
{
if (!_asyncOperation.isDone) return;
SetStatus();
}
}
public void WaitForAsyncComplete()
{
_isWaitForAsyncComplete = true;
int frame = 1000;
while (true)
{
frame--;
if (frame == 0)
{
break;
}
Update();
if (_provider.IsDone)
break;
}
}
public void Destroy()
{
_dependency.Release();
_asyncOperation = null;
}
private void SetStatus()
{
var sceneObj = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_provider.SceneObject = sceneObj;
_provider.SetStatus(NTaskStatus.Success);
}
private void SetStatus(string error)
{
_provider.SetStatus(NTaskStatus.Fail, error);
}
}
}