6.面板基类

6.面板基类


6.1 知识点

创建面板基类BasePanel.lua脚本,并在Lua主脚本初始化启动

LuaMain.lua

--初始化面板基类
require("BasePanel")

面板基类实现面向对象,并且定义一些成员,包括面板游戏对象,面板控件字典,初始化事件监听标识。

--利用面向对象
Object:subClass("BasePanel")

--面板对象
BasePanel.panelObj = nil

--相当于模拟一个字典 键为 控件名 值为控件本身
BasePanel.controls = {}

--事件监听标识
BasePanel.isInitEvent = false

定义面板初始化方法。接受一个参数 name,表示面板的名称。首先检查 self.panelObj 是否为 nil,如果是,则加载面板对象并设置为Canvas的子对象。使用 GetComponentsInChildren 方法查找面板对象下的所有UI控件脚本,然后按照一定的命名规则(如”btn”、”tog”、”img”等)筛选出需要的UI控件,并将它们存储在 self.controls 字典中。控件存储的形式是 { 控件名 = { 类型名 = 控件对象, 类型名 = 控件对象, … } }。

function BasePanel:Init(name)

    if self.panelObj == nil then

        --公共的实例化对象的方法 用AB包管理器加载对象
        self.panelObj = AssetBundleManager:LoadAssetBundleResource("ui", name, typeof(GameObject))

        --设置为Canvas子对象
        self.panelObj.transform:SetParent(Canvas, false)

        print(self.panelObj)

        --GetComponentsInChildren 找到所有UI控件脚本 存到字典中
        local allControls = self.panelObj:GetComponentsInChildren(typeof(UIBehaviour))

        --如果存入一些对于我们来说没用UI控件脚本 
        --为了避免 找各种无用控件 我们定一个规则 拼面板时 控件命名一定按规范来
        --Button btn名字
        --Toggle tog名字
        --Image img名字
        --ScrollRect sv名字
        for i = 0, allControls.Length-1 do

            print("当前allControls[i]是:",allControls[i])--打印出控件脚本所在的控件对象的名字和控件脚本类型

            --得到其中一个UI控件脚本的名字
            local controlName = allControls[i].name
            print("当前controlName是:"..controlName)--打印出控件脚本所在的控件对象的名字

            --按照名字的规则 去找控件 必须满足命名规则 才存起来
            if string.find(controlName, "btn") ~= nil or 
               string.find(controlName, "tog") ~= nil or 
               string.find(controlName, "img") ~= nil or 
               string.find(controlName, "sv") ~= nil or
               string.find(controlName, "txt") ~= nil then
                
                --为了让我们在取控件的时候 能够确定控件类型 所以需要存储类型
                --利用反射 Type 得到 控件的类名 
                local typeName = allControls[i]:GetType().Name

                --避免出现一个对象上 挂在多个UI控件 出现覆盖的问题 都会被存到一个容器中 相当于像列表数组的形式
                --意思就是,创建一个字典,键是控件所在的游戏对象名,值是存储所有ui组件的字典,这个字典的键是UI类型,值是具体控件脚本
                -- Dic<string,Dic<Type,UIBehaviour>>
                
                --最终存储形式 
                --{ btnRole = { Image = Image控件, Button = Button控件 },
                --  togItem = { Toggle = Toggle控件} }

                --有当前游戏对象key就直接赋值新的 没有就新创建丢进去
                if self.controls[controlName] ~= nil then
                    --通过自定义索引的形式 去加一个新的 “成员变量”
                    self.controls[controlName][typeName] = allControls[i]
                else
                    self.controls[controlName] = {[typeName] = allControls[i]}
                end
                
            end
        end

    end
end

定义得到面板控件方法。传入控件名和控件类型。不为空就返回面板控件字典中对应的控件。

--得到控件 根据 控件依附对象的名字 和 控件的类型字符串名字 Button Image Toggle
function BasePanel:GetControl(name, typeName)

    if self.controls[name] ~= nil then

        local sameNameControls = self.controls[name]

        if sameNameControls[typeName] ~= nil then
            return sameNameControls[typeName]
        end

    end

    return nil
end

实现显示隐藏面板方法。显示前要先初始化面板。

--显示面板
function BasePanel:ShowMe(name)
    self:Init(name)
    self.panelObj:SetActive(true)
end

--隐藏面板
function BasePanel:HideMe()
    self.panelObj:SetActive(false)
end

6.2 知识点代码

BasePanel.lua

--利用面向对象
Object:subClass("BasePanel")

--面板对象
BasePanel.panelObj = nil

--相当于模拟一个字典 键为 控件名 值为控件本身
BasePanel.controls = {}

--事件监听标识
BasePanel.isInitEvent = false

function BasePanel:Init(name)

    if self.panelObj == nil then

        --公共的实例化对象的方法 用AB包管理器加载对象
        self.panelObj = AssetBundleManager:LoadAssetBundleResource("ui", name, typeof(GameObject))

        --设置为Canvas子对象
        self.panelObj.transform:SetParent(Canvas, false)

        print(self.panelObj)

        --GetComponentsInChildren 找到所有UI控件脚本 存到字典中
        local allControls = self.panelObj:GetComponentsInChildren(typeof(UIBehaviour))

        --如果存入一些对于我们来说没用UI控件脚本 
        --为了避免 找各种无用控件 我们定一个规则 拼面板时 控件命名一定按规范来
        --Button btn名字
        --Toggle tog名字
        --Image img名字
        --ScrollRect sv名字
        for i = 0, allControls.Length-1 do

            print("当前allControls[i]是:",allControls[i])--打印出控件脚本所在的控件对象的名字和控件脚本类型

            --得到其中一个UI控件脚本的名字
            local controlName = allControls[i].name
            print("当前controlName是:"..controlName)--打印出控件脚本所在的控件对象的名字

            --按照名字的规则 去找控件 必须满足命名规则 才存起来
            if string.find(controlName, "btn") ~= nil or 
               string.find(controlName, "tog") ~= nil or 
               string.find(controlName, "img") ~= nil or 
               string.find(controlName, "sv") ~= nil or
               string.find(controlName, "txt") ~= nil then
                
                --为了让我们在取控件的时候 能够确定控件类型 所以需要存储类型
                --利用反射 Type 得到 控件的类名 
                local typeName = allControls[i]:GetType().Name

                --避免出现一个对象上 挂在多个UI控件 出现覆盖的问题 都会被存到一个容器中 相当于像列表数组的形式
                --意思就是,创建一个字典,键是控件所在的游戏对象名,值是存储所有ui组件的字典,这个字典的键是UI类型,值是具体控件脚本
                -- Dic<string,Dic<Type,UIBehaviour>>
                
                --最终存储形式 
                --{ btnRole = { Image = Image控件, Button = Button控件 },
                --  togItem = { Toggle = Toggle控件} }

                --有当前游戏对象key就直接赋值新的 没有就新创建丢进去
                if self.controls[controlName] ~= nil then
                    --通过自定义索引的形式 去加一个新的 “成员变量”
                    self.controls[controlName][typeName] = allControls[i]
                else
                    self.controls[controlName] = {[typeName] = allControls[i]}
                end
                
            end
        end

    end
end

--得到控件 根据 控件依附对象的名字 和 控件的类型字符串名字 Button Image Toggle
function BasePanel:GetControl(name, typeName)

    if self.controls[name] ~= nil then
    
        local sameNameControls = self.controls[name]
        if sameNameControls[typeName] ~= nil then
            return sameNameControls[typeName]
        end
        
    end
    
    return nil
end

--显示面板
function BasePanel:ShowMe(name)
    self:Init(name)
    self.panelObj:SetActive(true)
end

--隐藏面板
function BasePanel:HideMe()
    self.panelObj:SetActive(false)
end


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏