UE4页面管理

关卡

Level 分为主Level和子Level,主Level就是Scene, 子Level 应用其他页面3D场景需要或者是LevelStreamLevel加载配置
Level创建出来需要绑定一个主页面,主页面会放在ViewList的第一层,ViewList是来存储二级界面的数据对象

页面

Page 分为MainPage, FuncPage,LitePage;Page属于Scene的子元素
MainPage(一级界面)比如战斗界面的手操面板,世界主界面的手操面板,和Level 紧密联系在一起,共生共存;该面板存储在ViewList的首位
FuncPage(二级界面)比如点击主界面的仓库按钮,进入仓库界面,仓库界面就属于二级界面,该面板对象会放置在ViewList的里;
LitePage(三级界面)比如点击仓库界面,弹出装备详情面板等,该面板会放在二级界面里LiteList里; 三级界面为最小的页面单位;

区分二级界面和三级界面

一般是模块的主界面定义为二级界面,在二级界面上的操作弹出的界面就是三级界面,三级界面一般可以认为为内容比较简单的非全屏弹出页面,比如弹出框;比如:点击英雄按钮进入英雄列表界面,英雄列表界可以定义为二级界面,点击英雄,进入英雄主界面,也是二级界面,点击英雄装备界面,也是二级界面,点击装备详情界面的Icon弹出物品详情,就定义为三级界面,具体看页面的内容的定义;

相互关系

1.一级界面的Show和Hide 会受到仅仅会受到二级界面的影响,二级界面可以相互响应Hide和Over, 三级界面仅可以影响二级界面的数据和UI的刷新
2.Level的切换回影响所有的页面,所有的页面都会执行Over;

PageEnum.lua
--页面生命状态
PageActive =
{
    Ctor    = "Ctor",
    Over    = "Over",
    Show    = "Show",
    Hide    = "Hide",
}
PageActive = Enum("PageActive", PageActive)

--页面类型
PageCellType =
{
    MainPage     = "MainPage",    --一级界面
    FuncPage     = "FuncPage",    --二级界面 
    LitePage     = "LitePage",    --三级界面
}
PageCellType = Enum("PageCellType", PageCellType)

--页面路径组成
PagePathPart =
{
    PathPrefix     = "Game.View.Ctrl.",    
    PathSuffix     = "Ctrl",    
}
PagePathPart = Enum("PagePathPart", PagePathPart)

--页面指令
PageActionType =
{   
    Nothing      = "Nothing", 
    HideLastPage = "HideLastPage", 
    OverLastPage = "OverLastPage",
    DelLastPage  = "DelLastPage",
}
PageAction = Enum("PageActionType", PageActionType)
PageCore.lua
require "Game.View.PageEnum"
local PageScene = require "Game.View.PageScene"
local PageCore = {}

PageCore.LoginScene = "Page01Scene"
PageCore.HomeScene = "Page02Scene"

function PageCore:Ctor()
    self.SceneList      = {} --仅存儲场景界面
    self.CurScene       = false               
    self.CurView        = false 
    self.CurLite        = false       
    self.CurPath        = ""
end

function PageCore:Destroy()
end

function PageCore:EnterScene(SceneName, CtorArgs)
    if self.CurScene and self.CurScene.SceneName == SceneName then
        PrintTrace("Page:The current scene is already open !")
        return 
    end

    if SceneName == PageCore.LoginScene then
        self:__PushScene(SceneName, CtorArgs)
    else
        self:__DestoryCurScene()
        SceneMgr:OpenScene(SceneName, function() 
            self:__PushScene(SceneName, CtorArgs)
        end)
    end
end

function PageCore:BackScene()
    if #self.SceneList == 1 then
        PrintTrace("Page:A scene must be kept in the game !")
        return
    end
    self:__PopScene()

    local SceneName = self.SceneList[#self.SceneList].SceneName
    SceneMgr:OpenScene(SceneName, function() 
        self.CurScene = self.SceneList[#self.SceneList]
        self.CurView = self.CurScene:GetTopView()
        self.CurView:ReOpenView()
        self:PrintPath()
    end)
end

function PageCore:GoHomeScene()
    for Index, SceneObj in pairs(self.SceneList) do
        SceneObj:Destroy()
    end
    self.SceneList = {}
    self.CurScene  = false               
    self.CurView   = false 
    self.CurLite   = false 
    self:EnterScene(PageCore.HomeScene)
end

function PageCore:OpenView(ViewName, CtorArgs, PageType, PageAction)
    PageAction = PageAction or PageActionType.Nothing
    if self.CurScene:IsViewOpened(ViewName) then
        PrintTrace(string.format("Page: %s have been Opened !", ViewName))
        return 
    end
    local CurView = self.CurScene:PushView(ViewName, CtorArgs, PageType, PageAction)
    if PageType == PageCellType.LitePage then
        self.CurLite = CurView
    else
        self.CurView = CurView
    end
    self:PrintPath()
end

function PageCore:BackView()
    local CurView = self.CurScene:PopView()
    if CurView then
        if CurView.PageType == PageCellType.LitePage then
            self.CurLite = CurView
            self.CurLite:ReOpenView()
        else
            self.CurView = CurView
            self.CurView:ReOpenView()
        end
    else
        self.CurScene:GetTopView():ReOpenView()
        PrintTrace("Page: A page must be kept in the scene!")
    end
    self:PrintPath()
end

function PageCore:PrintPath(OutTag)
    if OutTag == nil then OutTag = "" end
    PrintTrace("<<------PageStack BGN-------->>"..OutTag)
    PrintTrace(self.SceneList)
    PrintTrace("<<------PageStack END-------->>"..OutTag)
end

function PageCore:__PushScene(SceneName, CtorArgs)
    self.CurScene = NewClass(PageScene):Init(SceneName, CtorArgs)
    table.insert(self.SceneList, self.CurScene)
    self.CurView = self.CurScene:GetTopView()
    self:PrintPath()
end

function PageCore:__DestoryCurScene()
    if self.CurScene then
        self.CurScene:Destroy()
    end
end

function PageCore:__PopScene()
    local PopScene = table.remove(self.SceneList)
    PopScene:Destroy()
    PopScene = nil
end

PageCore = RegisterClass("PageCore", PageCore, ClassObject)
return PageCore
PageScene.lua
local PageScene = {}
local PageView  = require "Game.View.PageView"

function PageScene:Ctor()
    self.SceneName      = ""
    self.ViewList       = {} --仅存儲2級界面
    self.State          = PageActive.Ctor
end

function PageScene:Destroy()
    for Index, ViewObj in pairs(self.ViewList) do
        ViewObj:Destroy()
    end
end

function PageScene:Init(SceneName, CtorArgs)
    self.ViewList  = {}
    self.SceneName = SceneName
    local LiteName = string.gsub(SceneName, "Scene", "")
    table.insert(self.ViewList, NewClass(PageView):Init(LiteName, CtorArgs, PageCellType.MainPage))
    return self
end

function PageScene:PushView(ViewName, CtorArgs, PageType, PageAction)
    self.ViewList[#self.ViewList]:UpdateActive(PageAction)
    if PageAction == PageActionType.DelLastPage then
        table.remove(self.ViewList):Destroy()
    end
    --
    local CurView = NewClass(PageView):Init(ViewName, CtorArgs, PageType)
    if PageType == PageCellType.LitePage then
        self.ViewList[#self.ViewList]:PushView(CurView)
    else
        table.insert(self.ViewList, CurView)
    end
    return CurView
end

function PageScene:PopView()
    local CurView = nil
    local ViewCell = #self.ViewList
    CurView = self.ViewList[ViewCell]
    if ViewCell > 1 then
        if CurView:PopView() then
            local LiteView = CurView:GetTopView()
            if LiteView then
                return LiteView
            else
                return CurView
            end
        else
            local CloseView = table.remove(self.ViewList)
            CloseView:Destroy()
            CloseView = nil
            return self.ViewList[#self.ViewList]
        end
    elseif ViewCell == 1 then
        if CurView:PopView() then
            local LiteView = CurView:GetTopView()
            if LiteView then
                return LiteView
            else
                return nil
            end
        else
            return nil
        end
    else
        error("Page:There is at least one element in the viewlist !")
    end
end

function PageScene:IsViewOpened(ViewName)
    for Index, ViewObj in pairs(self.ViewList) do
        if ViewObj.ViewName == ViewName then
            return true
        end
    end
    return false
end

function PageScene:GetTopView()
    return self.ViewList[#self.ViewList]
end

PageScene = RegisterClass("PageScene", PageScene, ClassObject)
return PageScene
PageView.lua
local PageView = {}

function PageView:Ctor()
    self.ViewName       = ""
    self.PageType       = ""
    self.ViewId         = false
    self.CtorArgs       = false
    self.LiteList       = {}--仅存儲三級界面
    self.State          = PageActive.Ctor
end

function PageView:Init(ViewName, CtorArgs, PageType)
    self.ViewName       = ViewName
    self.CtorArgs       = CtorArgs or false
    self.PageType       = PageType

    if PageType == PageCellType.LitePage then
        self.ViewId     = ViewMgr:AddMultiView(ViewName, CtorArgs)
    else
        ViewMgr:AddSingleView(ViewName, CtorArgs)
    end
    return self
end

function PageView:Destroy()
    self:__Over()
end

function PageView:ReOpenView()
    if self.State == PageActive.Over then
        self:__ReOpen()
    elseif self.State == PageActive.Hide then
        self:__Show()
    elseif self.State == PageActive.Ctor then
        PrintTrace("Page: No need to reopen the page!")
    end

end

function PageView:PushView(LiteView)
    table.insert(self.LiteList, LiteView)
end

function PageView:PopView()
    if #self.LiteList > 0 then
        table.remove(self.LiteList):Destroy()
        return true
    else
        return false
    end
end

function PageView:UpdateActive(PageAction)
    if PageAction == PageActionType.HideLastPage then
        self:__Hide()
        return
    end
    if PageAction == PageActionType.OverLastPage or PageActionType.DelLastPage then
        self:__Over()
        return
    end
end

function PageView:GetTopView()
    if #self.LiteList > 0 then
        return self.LiteList[#self.LiteList]
    else
        return nil
    end
end

function PageView:__Hide()
    if self.PageType == PageCellType.LitePage then
        ViewMgr:HideMultiView(self.ViewId)
    else
        ViewMgr:HideSingleView(self.ViewName)
    end
    self.State = PageActive.Hide

    for Index, ViewObj in pairs(self.LiteList) do
        ViewObj:__Hide()
    end
end

function PageView:__Show()
    if self.PageType == PageCellType.LitePage then
        ViewMgr:ShowMultiView(self.ViewId)
    else
        ViewMgr:ShowSingleView(self.ViewName)
    end
    self.State = PageActive.Show

    for Index, ViewObj in pairs(self.LiteList) do
        ViewObj:__Show()
    end
end

function PageView:__ReOpen()
    if self.PageType == PageCellType.LitePage then
        self.ViewId = ViewMgr:AddMultiView(self.ViewName, self.CtorArgs or nil)
    else
        ViewMgr:AddSingleView(self.ViewName, self.CtorArgs or nil)
    end
    self.State = PageActive.Ctor

    for Index, ViewObj in pairs(self.LiteList) do
        ViewObj:__ReOpen()
    end
end

function PageView:__Over()
    if self.PageType == PageCellType.LitePage then
        ViewMgr:RemoveMultiView(self.ViewId)
    else
        ViewMgr:RemoveSingleView(self.ViewName)
    end
    self.State = PageActive.Over

    for Index, ViewObj in pairs(self.LiteList) do
        ViewObj:__Over()
    end
end

PageView = RegisterClass("PageView", PageView, ClassObject)
return PageView
SceneMgr .lua
SceneMgr = {}

function SceneMgr:Ctor()
    self.CallBack = 0
end

function SceneMgr:Destroy()
end

function SceneMgr:OpenScene(MapName, CallBack)
    self.CallBack = CallBack
    CSceneMgr.Instance():OpenScene(MapName)
end

function SceneMgr:LoadComplete(MapPath)
    self.CallBack()
end

SceneMgr = RegisterClass("SceneMgr", SceneMgr, ClassObject)
SceneMgr = NewClass(SceneMgr)
return SceneMgr

你可能感兴趣的:(UE4页面管理)