谢谢大家关注一下啊我的微信
框架上 设计一个 基类 SceneLoad:BaseSceneLoad
设计多个 场景类:NormalSceneLoad 例如:
BaseSceneLoad
:引入基础场景加载模式。NormalSceneLoad
:引入普通场景加载模式。PrefabSceneLoad
:引入预制体场景加载模式。这次 设计一个 场景基类 SceneBase ,这个类提供了一个框架,用于处理场景的加载、初始化、激活、释放等生命周期管理,以及进度更新和用户界面显示。开发者需要根据具体的场景需求,重写一些虚函数以实现特定的功能。
定义 这个类的构造函数或初始化函数:
1. `self._name = params.name` 场景名字
2. `self._dataProgress = 0` 和 `self._totalProgress = 0`:
- 这两行代码初始化了两个私有变量`_dataProgress`和`_totalProgress`,分别表示数据加载的进度和总进度,初始值都为0。
3. `self._loadingView = nil`:
- 这行代码初始化了一个私有变量`_loadingView`,并将其设置为`nil`。用于存储加载界面 进度条。
4. `self._data = params.data`:存储需要加载的数据。
5. `self._active = false`:当前模块或场景是否处于活动状态。
6. `self._extra_res_loader = {}`:用于存储额外的资源加载器。
7. `self._autoClosePanles = {}`:用于存储需要自动关闭的面板。
8. `self._sceneLoad = nil`:用于存储场景加载的相关信息。
9. `self._isDispose = false`:用于表示当前对象是否已经被释放。
10. `self._progressConfig = {}`:存储进度配置信息。
11. `self._progressValue = {}`:存储进度值。
12. `self._isResumeing = false`:是否正在恢复。
然后 设计函数思路:
代码:
--[[
Description: 场景基类
--]]
---
local SceneBase = class("SceneBase")
function SceneBase:initialize(params)
self._name = params.name
self._dataProgress = 0
self._totalProgress = 0
self._loadingView = nil
self._data = params.data
self._active = false
self._extra_res_loader = {}
self._autoClosePanles = {}
self._sceneLoad = nil
self._isDispose = false
self._progressConfig = {}
self._progressValue = {}
self._isResumeing = false
self:setProgressConfig(SceneManager.stateEnum.loadLoadingScene, self:getInterimLoadPercent())
self:setProgressConfig(SceneManager.stateEnum.loadNewScene, self:getScenePercent())
self:setProgressConfig(SceneManager.stateEnum.loadingNewData, self:getExtraDataTotalPercent())
end
function SceneBase:dispose()
if self._isDispose then
-- 解决onNewSceneLoaded,onNewSceneFinish 问题
return
end
self._isDispose = true
self._name = nil
self._dataProgress = nil
self._totalProgress = nil
self._loadingView = nil
self._data = nil
if self._sceneRoot then
print("release scene self._sceneRoot")
CSharpImport.GameObject.Destroy(self._sceneRoot)
self._sceneRoot = nil
end
for i, v in pairs(self._extra_res_loader) do
v:release()
end
self._extra_res_loader = nil
self:releaseSceneLoad()
end
function SceneBase:releaseSceneLoad()
if self._sceneLoad then
self._sceneLoad:dispose()
self._sceneLoad = nil
end
end
function SceneBase:getName()
return self._name
end
---@return boolean
function SceneBase:isActive()
return self._active
end
---@param isActive boolean
function SceneBase:setActive(isActive)
self._active = isActive
end
---@return boolean 是否是起始场景
function SceneBase:isInitScene()
return false
end
function SceneBase:getSceneLoad()
return self._sceneLoad
end
-- 此处为切换场景时,由场景管理器通知释放场景lua表,根据各自场景自身需求做处理
function SceneBase:onDestroyScene()
assert(false, "override")
end
function SceneBase:getLoadingLuaPath()
end
function SceneBase:getScenePrefabResPath()
assert(false, "override")
end
function SceneBase:getScenePrefab()
return self._sceneRoot
end
function SceneBase:getSceneResPath()
assert(false, "override")
end
function SceneBase:loadUnitySceneAsync()
local path = self:getSceneResPath()
return g.loaderManager:loadSceneAsync(path)
end
function SceneBase:onSceneResStartLoad()
end
function SceneBase:onSceneResLoaded()
end
function SceneBase:loadScenePrefab(prefabPath)
return Global.loaderManager:loadPrefabAsync(prefabPath)
end
function SceneBase:getSceneObj()
return self._sceneObj
end
function SceneBase:onSceneSwitchStart()
end
function SceneBase:onPreSceneExit(finishCallback)
assert(false, "override")
end
--- 在newScene 的onSceneResLoaded之后调用
--- 注意,此时Scene对象已经调用过dispose
function SceneBase:onNewSceneLoaded()
assert(false, "override")
end
function SceneBase:onNewSceneStartLoaded()
-- assert(false, "override")
end
--- 在newScene 的 onExtraDataCompleted 之前调用
--- 注意,此时Scene对象已经调用过dispose
function SceneBase:onNewSceneFinish(finishCallback)
assert(false, "override")
end
---@param progress number
function SceneBase:onProgress(progress)
if progress == 0 then
if not self._loadingView then
local panelPath = self:getLoadingLuaPath()
if panelPath then
print("show scene loading")
self._loadingView =
g.uiManager:showPanel(
panelPath,
self:createLoadingPanelParam(),
function()
self:onLoadingPanelOpen()
end
)
end
end
end
if self._loadingView and self._loadingView:getState() == UIManager.State.Normal then
self._loadingView:setProgress(progress)
end
end
function SceneBase:setProgressConfig(key, percent)
self._progressConfig[key] = percent
end
function SceneBase:setProgressValue(key, value)
self._progressValue[key] = value
local totalProgress = 0
for cKey, cValue in pairs(self._progressConfig) do
local pWeight = self._progressConfig[cKey] or 0
local pValue = self._progressValue[cKey] or 0
totalProgress = totalProgress + pWeight * pValue
print("setProgressValue", cKey, pValue, pWeight)
end
self:onProgress(totalProgress)
print("setProgressValue totalProgress", key, totalProgress)
end
function SceneBase:createLoadingPanelParam()
end
function SceneBase:onLoadingPanelOpen()
end
function SceneBase:initData()
end
---@return boolean @初始化完成返回true
function SceneBase:isInitDataComplete()
return true
end
function SceneBase:getInitDataProgress()
return 1
end
function SceneBase:getInterimLoadPercent()
return 0.02
end
function SceneBase:getScenePercent()
return 0.4
end
function SceneBase:getSceneType()
return SceneEnum.sceneType.unity
end
function SceneBase:getExtraDataTotalPercent()
return 1 - self:getInterimLoadPercent() - self:getScenePercent()
end
--@desc 进行扩展数据加载
---@return number @ 返回加载进度百分比
function SceneBase:onExtraDataProgress()
return self._dataProgress
end
---@param call function
function SceneBase:onExtraDataCompleted(call)
self._dataProgress = 1
self._totalProgress = 1
call()
end
---@param call function
function SceneBase:closeLoadingPanel(call)
if self._loadingView then
-- 并不需要等待loading完全结束
g.uiManager:hidePanel(self:getLoadingLuaPath())
self._loadingView = nil
if call then
call()
end
else
if call then
call()
end
end
end
--@desc 完全结束
function SceneBase:onLoadingCompleted()
end
function SceneBase:onFinish(call)
self:enterWithData(self._data,
function()
self:closeLoadingPanel(call)
end
)
end
function SceneBase:enterWithData(data, call)
call()
end
function SceneBase:resumeScene(data)
self._isResumeing = true
self:onPreResumeSceneExit(data, function()
self:onSceneExit()
self:onResumeSceneExit(data)
self:setActive(true)
self:enterWithData(self._data,
function()
self:onPostResumeScene(data)
end
)
end)
end
function SceneBase:onPreResumeSceneExit(data, callBack)
if callBack then
callBack()
end
end
function SceneBase:onPostResumeScene(data)
self._isResumeing = false
end
--@desc 当场景退出
function SceneBase:onSceneExit()
self:setActive(false)
end
function SceneBase:onResumeSceneExit(data)
end
function SceneBase:addAutoClosePanle(panelUiName)
self._autoClosePanles[#self._autoClosePanles + 1] = panelUiName
end
function SceneBase:getAutoClosePanleList()
return self._autoClosePanles
end
function SceneBase:clearAutoClosePanle()
self._autoClosePanles = {}
end
function SceneBase:getExtraLoaderByPath(path)
return self._extra_res_loader[path]
end
---@param curScene SceneBase
---@return BaseSceneLoad
function SceneBase:createSceneLoad(hasStacked)
local sceneType = self:getSceneType()
if sceneType == SceneEnum.sceneType.AdditivePrefab then
self._sceneLoad = AdditiveSceneLoad:new()
Logger.filter("Scene step", "AdditiveSceneLoad:initialize", self:getName(), debug.traceback())
elseif sceneType == SceneEnum.sceneType.prefab then
self._sceneLoad = PrefabSceneLoad:new()
Logger.filter("Scene step", "PrefabSceneLoad:initialize", self:getName(), debug.traceback())
elseif sceneType == SceneEnum.sceneType.dontDestoryUnit then
if hasStacked then
Logger.filter("Scene step", "UnloadAdditiveSceneLoad:initialize", self:getName(), debug.traceback())
self._sceneLoad = UnloadAdditiveSceneLoad:new()
else
self._sceneLoad = DontDestorySceneLoad:new()
Logger.filter("Scene step", "DontDestorySceneLoad:initialize", self:getName(), debug.traceback())
end
elseif sceneType == SceneEnum.sceneType.unloadAdditivePrefab then
self._sceneLoad = UnloadAdditiveSceneLoad:new()
Logger.filter("Scene step", "UnloadAdditiveSceneLoad:initialize", self:getName(), debug.traceback())
else
self._sceneLoad = NormalSceneLoad:new()
Logger.filter("Scene step", "NormalSceneLoad:initialize", self:getName(), debug.traceback())
end
return self._sceneLoad
end
function SceneBase.addCmd(queue, func, object, p1, p2, p3)
queue[#queue + 1] = {func = func, obj = object, param1 = p1, param2 = p2, param3 = p3}
end
function SceneBase:executeCmd(queue, cmdIndex)
local info = queue[cmdIndex]
if info.obj then
info.func(info.obj, info.param1, info.param2, info.param3)
else
info.func(info.param1, info.param2, info.param3)
end
end
function SceneBase:executeQueue(q, cmdIndex, breakExecuteCallback)
assert(q, "执行命令队列不能为空")
local total = #q
local tmpCmdIndex = cmdIndex
if tmpCmdIndex < total then
local cmdExeStart = os.clock()
while (os.clock() - cmdExeStart) < 0.015 and tmpCmdIndex < total do
tmpCmdIndex = tmpCmdIndex + 1
self:executeCmd(q, tmpCmdIndex)
if breakExecuteCallback and breakExecuteCallback() then
break
end
end
-- print("executeQueue", cmdIndex, tmpCmdIndex, tmpCmdIndex - cmdIndex, os.clock() - cmdExeStart)
return false, tmpCmdIndex
else
return true, tmpCmdIndex
end
end
return SceneBase
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务