c1_lua/lua/app/scene/scene_manager.lua
2023-04-03 10:59:13 +08:00

229 lines
6.0 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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