unity 预加载场景
思路:
1.创建 加载场景异步函数字典用于存放加载场景的异步变量
2.当加载场景或者预加载的时候字典里记录异步函数
3.当加载场景时候如果异步变量有的话,自动切换场景切换为true.如果已经异步已经为true,就直接切换场景,如果没有的话需要异步加载,并且自动切换场景为true
4.异步加载场景时候只需要将异步变量自动切换场景为false即可
代码:
using System;
using System.Collections.Generic;
using DJ;
using Sirenix.Utilities;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace ET
{
public class LoadSceneComponentUpdateSystem:UpdateSystem
{
public override void Update(LoadSceneComponent self)
{
}
}
public class LoadSceneComponentAwakeSystem:AwakeSystem
{
public override void Awake(LoadSceneComponent self)
{
self.preLoadSceneDict =new Dictionary();
}
}
public class LoadSceneComponentDestroySystem:DestroySystem
{
public override void Destroy(LoadSceneComponent self)
{
}
}
public static class LoadSceneComponentSystem
{
///
/// 加载场景
///
///
///
public static void LoadScene(this LoadSceneComponent self,string sceneName)
{
#if UNITY_EDITOR
UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode($"Assets/Bundles/Map/{sceneName}/{sceneName}.unity",
new LoadSceneParameters(LoadSceneMode.Single,LocalPhysicsMode.None));
#else
SceneManager.LoadScene(sceneName);
#endif
}
///
/// 异步加载场景
///
///
///
///
///
public static AsyncOperation LoadSceneAsync(this LoadSceneComponent self,string sceneName,
LoadSceneMode loadSceneMode =LoadSceneMode.Single)
{
self.preLoadSceneDict.TryGetValue(sceneName,out var loadMapOperation);
if (loadMapOperation !=null)
{
loadMapOperation.allowSceneActivation =true;
return loadMapOperation;
}
#if UNITY_EDITOR
loadMapOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(
$"Assets/Bundles/Map/{sceneName}/{sceneName}.unity",
new LoadSceneParameters(loadSceneMode,LocalPhysicsMode.None));
#else
loadMapOperation = SceneManager.LoadSceneAsync(sceneName, new LoadSceneParameters(loadSceneMode, LocalPhysicsMode.None));
#endif
self.preLoadSceneDict.Add(sceneName, loadMapOperation);
return loadMapOperation;
}
///
/// 预加载场景
///
///
///
///
///
public static AsyncOperation PreloadSceneAsync(this LoadSceneComponent self,string sceneName,
LoadSceneMode loadSceneMode =LoadSceneMode.Single)
{
self.preLoadSceneDict.TryGetValue(sceneName,out var loadMapOperation);
if (loadMapOperation !=null)
{
return loadMapOperation;
}
#if UNITY_EDITOR
loadMapOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(
$"Assets/Bundles/Map/{sceneName}/{sceneName}.unity",
new LoadSceneParameters(loadSceneMode,LocalPhysicsMode.None));
#else
loadMapOperation = SceneManager.LoadSceneAsync(sceneName, new LoadSceneParameters(loadSceneMode, LocalPhysicsMode.None));
#endif
loadMapOperation.allowSceneActivation =false;
self.preLoadSceneDict.Add(sceneName, loadMapOperation);
return loadMapOperation;
}
///
/// 获取场景异步操作
///
///
///
///
public static AsyncOperation GetAsyncOperationByName(this LoadSceneComponent self,string mapName)
{
self.preLoadSceneDict.TryGetValue(mapName,out var asyncOperation);
return asyncOperation;
}
///
/// 卸载场景
///
///
///
public static void UnloadScene(this LoadSceneComponent self,string mapName,bool unloadScene =true)
{
var asyncOperation = self.GetAsyncOperationByName(mapName);
if (asyncOperation !=null)
{
self.preLoadSceneDict.Remove(mapName);
if (unloadScene)
{
var scene =SceneManager.GetSceneByName(mapName);
if (scene.IsValid())
{
var asyncOperation2 =SceneManager.UnloadSceneAsync(scene);
if (asyncOperation2 !=null)
{
asyncOperation2.completed+= operation => {Log.Info($"真正卸载了{mapName}场景资源"); };
}
}
}
}
}
///
/// 获取进度
///
///
///
public static int Process(this LoadSceneComponent self,string sceneName)
{
self.preLoadSceneDict.TryGetValue(sceneName,out var loadMapOperation);
if (loadMapOperation ==null)
{
return 0;
}
var currProgress =Convert.ToInt32(loadMapOperation.progress *100);
return currProgress;
}
}
}