229 lines
6.0 KiB
Lua
229 lines
6.0 KiB
Lua
local SceneManager = {
|
||
currentSceneName = "",
|
||
targetSceneName = ""
|
||
}
|
||
|
||
local ASYNC_FINISH_PROGRESS = 0.899
|
||
|
||
local EMPTY_SCENE_PATH = "assets/scenes/empty_scene.unity"
|
||
|
||
SceneManager.SCENE_NAME = {
|
||
MAIN_CITY = "app/scene/maincity/maincity_scene",
|
||
BATTLE = "app/scene/battle/battle_scene",
|
||
}
|
||
|
||
-- sceneName:目标场景路径,这里是lua的路径,不是资源的路径
|
||
-- showLoading:显示指定的加载界面
|
||
-- callback:切换完成后的回调
|
||
-- immediately:是否立即切换,是的话会直接切换到目标场景,否则的话会创建一个空场景并先切换到空场景,然后垃圾回收,然后再切换到目标场景
|
||
-- keepUI:是否关闭所有UI界面
|
||
-- preloadList:下一个场景加载完后需要预加载的资源列表
|
||
-- closeLoadingCallback:关闭过场动画时的callback
|
||
|
||
function SceneManager:_changeScene(params)
|
||
local sceneName = params.sceneName or ""
|
||
if sceneName == "" then
|
||
return false
|
||
end
|
||
-- 正在切换场景中
|
||
if self.targetSceneName ~= "" then
|
||
return false
|
||
end
|
||
-- 当前场景就是目标场景
|
||
if self.currentSceneName == sceneName then
|
||
if not params.reloadScene then
|
||
return false
|
||
end
|
||
params.immediately = false
|
||
end
|
||
self.params = params
|
||
self.targetSceneName = sceneName
|
||
return true
|
||
end
|
||
|
||
function SceneManager:changeScene(params)
|
||
if not self:_changeScene(params) then
|
||
return false
|
||
end
|
||
UIManager:disableTouch()
|
||
UIManager:showLoading(self.params.showLoading, function()
|
||
self:loadScene()
|
||
end)
|
||
return true
|
||
end
|
||
|
||
function SceneManager:loadScene()
|
||
if not self.params.keepUI then
|
||
UIManager:closeAllUI()
|
||
end
|
||
UIManager:hideToastAndMessageBox()
|
||
self.targetScene = require(self.targetSceneName):create(self.params.sceneParams)
|
||
if self.params.immediately then
|
||
self:loadSceneABAsync()
|
||
else
|
||
self:createEmptyScene(function()
|
||
self:loadSceneABAsync()
|
||
end)
|
||
end
|
||
end
|
||
|
||
function SceneManager:createEmptyScene(nextStep)
|
||
local function loadEmptyScene()
|
||
local realPath = ResourceManager:getSceneLoadPath(EMPTY_SCENE_PATH)
|
||
local asyncOperation = CS.UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(realPath, CS.LoadSceneMode.Additive)
|
||
asyncOperation.allowSceneActivation = false
|
||
self:scheduleGlobal(function()
|
||
if asyncOperation.progress >= ASYNC_FINISH_PROGRESS then
|
||
if not asyncOperation.allowSceneActivation then
|
||
if self.currentScene then
|
||
self.currentScene:_onClose()
|
||
end
|
||
asyncOperation.allowSceneActivation = true
|
||
end
|
||
end
|
||
if asyncOperation.isDone then
|
||
nextStep()
|
||
return true
|
||
end
|
||
end, 0.01)
|
||
end
|
||
if USE_AB then
|
||
ResourceManager:loadSceneAsync(EMPTY_SCENE_PATH, function()
|
||
loadEmptyScene()
|
||
end)
|
||
else
|
||
loadEmptyScene()
|
||
end
|
||
end
|
||
|
||
function SceneManager:loadSceneABAsync()
|
||
if USE_AB then
|
||
local resPath = self.targetScene:getResPath()
|
||
ResourceManager:loadSceneAsync(resPath, function()
|
||
self:LoadSceneAsync()
|
||
end)
|
||
else
|
||
self:LoadSceneAsync()
|
||
end
|
||
end
|
||
|
||
function SceneManager:LoadSceneAsync()
|
||
local resPath = self.targetScene:getResPath()
|
||
local realPath = ResourceManager:getSceneLoadPath(resPath)
|
||
local asyncOperation = CS.UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(realPath, CS.LoadSceneMode.Additive)
|
||
asyncOperation.allowSceneActivation = false
|
||
self:scheduleGlobal(function()
|
||
if asyncOperation.progress >= ASYNC_FINISH_PROGRESS then
|
||
if not asyncOperation.allowSceneActivation then
|
||
if self.params.immediately and self.currentScene then
|
||
self.currentScene:_onClose()
|
||
end
|
||
asyncOperation.allowSceneActivation = true
|
||
end
|
||
end
|
||
if asyncOperation.isDone then
|
||
self:onLoadSceneFinished()
|
||
return true
|
||
end
|
||
end, 0.01)
|
||
end
|
||
|
||
function SceneManager:onLoadSceneFinished()
|
||
local function nextStep()
|
||
if self.currentScene then
|
||
local resPath = self.currentScene:getResPath()
|
||
ResourceManager:unloadScene(resPath)
|
||
end
|
||
if not self.params.immediately then
|
||
ResourceManager:unloadScene(EMPTY_SCENE_PATH)
|
||
end
|
||
if self.params.preloadList then
|
||
local preloadCount = #self.params.preloadList
|
||
local loadedCount = 0
|
||
local function loadCheck( asset )
|
||
loadedCount = loadedCount + 1
|
||
local ratio = loadedCount / preloadCount
|
||
if loadedCount >= preloadCount then
|
||
self:onFinished()
|
||
end
|
||
end
|
||
if preloadCount > 0 then
|
||
for i, resPath in ipairs(self.params.preloadList) do
|
||
ResourceManager:asyncLoad(resPath, loadCheck)
|
||
end
|
||
else
|
||
self:onFinished()
|
||
end
|
||
else
|
||
self:onFinished()
|
||
end
|
||
end
|
||
self:garbageCollect(nextStep)
|
||
end
|
||
|
||
function SceneManager:onFinished()
|
||
LocalData:save()
|
||
self.targetScene:_init(self.params.init)
|
||
if self.targetScene:closeLoadingAuto() then
|
||
UIManager:closeLoading(self.params.closeLoadingCallback)
|
||
UIManager:enableTouch()
|
||
else
|
||
if self.params.closeLoadingCallback then
|
||
self.targetScene:addCloseLoadingCallback(self.params.closeLoadingCallback)
|
||
end
|
||
end
|
||
self.currentSceneName = self.targetSceneName
|
||
self.currentScene = self.targetScene
|
||
self.targetSceneName = ""
|
||
self.targetScene = nil
|
||
local finishCallback = self.params.callback
|
||
self.params = nil
|
||
if finishCallback then
|
||
finishCallback(self.currentScene)
|
||
end
|
||
end
|
||
|
||
function SceneManager:getCurrentScene()
|
||
return self.currentScene
|
||
end
|
||
|
||
function SceneManager:getCurrentSceneName()
|
||
return self.currentSceneName
|
||
end
|
||
|
||
function SceneManager:getIsInMainCityScene()
|
||
return self.currentSceneName == SceneManager.SCENE_NAME.MAIN_CITY
|
||
end
|
||
|
||
function SceneManager:garbageCollect(callback)
|
||
ResourceManager:unloadAllDelayAssets()
|
||
CS.BF.BFMain.Instance.LuaMgr:LuaEnvFullGC(30000)
|
||
collectgarbage("collect")
|
||
local asyncOperation = CS.UnityEngine.Resources.UnloadUnusedAssets()
|
||
local function onUnloadComplete(opration)
|
||
asyncOperation:completed("-", onUnloadComplete)
|
||
if callback then
|
||
callback()
|
||
end
|
||
end
|
||
|
||
asyncOperation:completed("+", onUnloadComplete)
|
||
end
|
||
|
||
function SceneManager:scheduleGlobal(func, inter)
|
||
SchedulerManager:scheduleGlobal(func, inter)
|
||
end
|
||
|
||
function SceneManager:clear()
|
||
end
|
||
|
||
-- 只有一个场景
|
||
function SceneManager:enterMainScene()
|
||
local scene = "app/scene/main/main_scene"
|
||
self.mainScene = require(scene):create()
|
||
self.mainScene:init()
|
||
|
||
self.currentScene = self.mainScene
|
||
end
|
||
|
||
return SceneManager |