ZoeAppClass/Library/PackageCache/com.unity.addressables@1.1.10/Runtime/ResourceManager/ResourceProviders/SceneProvider.cs

181 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine.ResourceManagement;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.SceneManagement;
namespace UnityEngine.ResourceManagement.ResourceProviders
{
/// <summary>
/// Implementation if ISceneProvider
/// </summary>
public class SceneProvider : ISceneProvider
{
class SceneOp : AsyncOperationBase<SceneInstance>, IUpdateReceiver
{
bool m_ActivateOnLoad;
SceneInstance m_Inst;
IResourceLocation m_Location;
LoadSceneMode m_LoadMode;
int m_Priority;
private AsyncOperationHandle<IList<AsyncOperationHandle>> m_DepOp;
ResourceManager m_ResourceManager;
public SceneOp(ResourceManager rm)
{
m_ResourceManager = rm;
}
public void Init(IResourceLocation location, LoadSceneMode loadMode, bool activateOnLoad, int priority, AsyncOperationHandle<IList<AsyncOperationHandle>> depOp)
{
m_DepOp = depOp;
if (m_DepOp.IsValid())
m_DepOp.Acquire();
m_Location = location;
m_LoadMode = loadMode;
m_ActivateOnLoad = activateOnLoad;
m_Priority = priority;
}
protected override void GetDependencies(List<AsyncOperationHandle> deps)
{
if (m_DepOp.IsValid())
deps.Add(m_DepOp);
}
protected override string DebugName { get { return string.Format("Scene({0})", m_Location == null ? "Invalid" : ShortenPath(m_Location.InternalId, false)); } }
protected override void Execute()
{
var loadingFromBundle = false;
if (m_DepOp.IsValid())
{
foreach (var d in m_DepOp.Result)
{
var abResource = d.Result as IAssetBundleResource;
if (abResource != null && abResource.GetAssetBundle() != null)
loadingFromBundle = true;
}
}
m_Inst = InternalLoadScene(m_Location, loadingFromBundle, m_LoadMode, m_ActivateOnLoad, m_Priority);
((IUpdateReceiver)this).Update(0.0f);
}
internal SceneInstance InternalLoadScene(IResourceLocation location, bool loadingFromBundle, LoadSceneMode loadMode, bool activateOnLoad, int priority)
{
var op = InternalLoad(location.InternalId, loadingFromBundle, loadMode);
op.allowSceneActivation = activateOnLoad;
op.priority = priority;
return new SceneInstance() { m_Operation = op, Scene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1) };
}
AsyncOperation InternalLoad(string path, bool loadingFromBundle, LoadSceneMode mode)
{
#if !UNITY_EDITOR
return SceneManager.LoadSceneAsync(path, new LoadSceneParameters() { loadSceneMode = mode });
#else
if (loadingFromBundle)
return SceneManager.LoadSceneAsync(path, new LoadSceneParameters() { loadSceneMode = mode });
else
{
if (path.ToLower().LastIndexOf("assets/") == -1)
path = "Assets/" + path;
if (path.LastIndexOf(".unity") == -1)
path += ".unity";
return UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(path, new LoadSceneParameters() { loadSceneMode = mode });
}
#endif
}
protected override void Destroy()
{
//the scene will be unloaded via the UnloadSceneOp as it waits correctlyf or the unload to complete before releasing the load op
if (m_DepOp.IsValid())
m_DepOp.Release();
base.Destroy();
}
protected override float Progress
{
get
{
return (m_Inst.m_Operation.progress + m_DepOp.PercentComplete) / 2;
}
}
void IUpdateReceiver.Update(float unscaledDeltaTime)
{
if (m_Inst.m_Operation.isDone || (!m_ActivateOnLoad && m_Inst.m_Operation.progress == .9f))
Complete(m_Inst, true, null);
}
}
class UnloadSceneOp : AsyncOperationBase<SceneInstance>
{
SceneInstance m_Instance;
AsyncOperationHandle<SceneInstance> m_sceneLoadHandle;
public void Init(AsyncOperationHandle<SceneInstance> sceneLoadHandle)
{
if (sceneLoadHandle.ReferenceCount > 0)
{
m_sceneLoadHandle = sceneLoadHandle;
m_Instance = m_sceneLoadHandle.Result;
}
}
protected override void Execute()
{
if (m_sceneLoadHandle.IsValid())
{
var unloadOp = SceneManager.UnloadSceneAsync(m_sceneLoadHandle.Result.Scene);
if (unloadOp == null)
UnloadSceneCompleted(null);
else
unloadOp.completed += UnloadSceneCompleted;
}
else
Complete(m_Instance, true, "");
}
private void UnloadSceneCompleted(AsyncOperation obj)
{
if (m_sceneLoadHandle.IsValid())
m_sceneLoadHandle.Release();
Complete(m_Instance, true, "");
}
protected override float Progress
{
get { return m_sceneLoadHandle.PercentComplete; }
}
}
/// <inheritdoc/>
public AsyncOperationHandle<SceneInstance> ProvideScene(ResourceManager resourceManager, IResourceLocation location, LoadSceneMode loadMode, bool activateOnLoad, int priority)
{
AsyncOperationHandle<IList<AsyncOperationHandle>> depOp = default(AsyncOperationHandle<IList<AsyncOperationHandle>>);
if (location.HasDependencies)
depOp = resourceManager.ProvideResourceGroupCached(location.Dependencies, location.DependencyHashCode, typeof(IAssetBundleResource), null);
SceneOp op = new SceneOp(resourceManager);
op.Init(location, loadMode, activateOnLoad, priority, depOp);
var handle = resourceManager.StartOperation<SceneInstance>(op, depOp);
if (depOp.IsValid())
depOp.Release();
return handle;
}
/// <inheritdoc/>
public AsyncOperationHandle<SceneInstance> ReleaseScene(ResourceManager resourceManager, AsyncOperationHandle<SceneInstance> sceneLoadHandle)
{
var unloadOp = new UnloadSceneOp();
unloadOp.Init(sceneLoadHandle);
return resourceManager.StartOperation(unloadOp, sceneLoadHandle);
}
}
}