简单的UI框架 | 五、开发BasePanel面板基类和控制UI面板Prefab的实例化创建和管理

简单的UI框架

开发BasePanel面板基类和控制UI面板Prefab的实例化创建和管理




一、BasePanel基类

每个面板都有共有的功能,所以说给每个面板一个共有的基类BasePanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasePanel : MonoBehaviour
{
    
    

}

让所有的面板都基础BasePanel这样就可以再UIManager中管理。
这里BasePanel需要继承与MonoBehaviour,因为他要挂载到我们的场景对象上。我们先新建立一个空的BasePanel脚本,后续再对功能进行完善。

接下来我们对每个UI面板进行操作。
我们只需要在每个UI面板下建立一个脚本,脚本继承BasePanel即可。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TextPanel : BasePanel
{
    
    

}

接下来我们对UI面板进行控制。

二、控制UI面板Prefab的实例化创建和管理

回到我们的UIManager,我们需要在这里管理我们的UI面板。
我们在创建一个字典,用来保存我们所以实例化的面板。

private Dictionary<UIType, BasePanel> panelDict;//保存所以实例化面板的游戏物体身上的BasePanel组件

Key当然就是这个面板的UITypeValue可以直接保存这个游戏物体,同样也可以保存这个游戏物体身上的组件。这里我直接保存了BasePanel组件。

我们创建一个方法用来得到实例化的面板。

 public BasePanel GetPanel(UIType panelType)
    {
    
    

    }

首先我们要检查这个字典里有没有这个面板,如果没有我们创建这个面板,如果有直接返回这个面板。

扫描二维码关注公众号,回复: 15068275 查看本文章
    public BasePanel GetPanel(UIType panelType)
    {
    
    
        if (panelDict == null)
        {
    
    
            panelDict = new Dictionary<UIType, BasePanel>();
        }

        BasePanel panel;
        panelDict.TryGetValue(panelType, out panel)}

我们怎么得到这个面板,分两步:
1、定义一个要得到的类型。
2、调用字典的TryGetValue方法,把Key传递过去。
接下来我们判断一下这个panel有没有得到。

    public BasePanel GetPanel(UIType panelType)
    {
    
    
        if (panelDict == null)
        {
    
    
            panelDict = new Dictionary<UIType, BasePanel>();
        }

        BasePanel panel;
        panelDict.TryGetValue(panelType, out panel);

        if (panel == null)
        {
    
    
            //如果找不到,那么就找这个面板的Prefab的路径,然后去根据Prefab去实例化面板
            string path;
            panelPathDict.TryGetValue(panelType, out path);
            GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
            instPanel.transform.SetParent(canvasTransform);
            panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());
            return instPanel.GetComponent<BasePanel>();
        }
        else
        {
    
    
            return panel;
        }
    }

如果为空,说明我们从来没有实例化过这个panelType的面板,我们就要根据

private Dictionary<UIType, string> panelPathDict;//存储所有的面板Prefab的路径

这个字典取到Prefab的路径来实例化他。
这里我们得到路径,然后去加载他。
因为我们的面板都放在了Resource文件下的路径,所以我们可以直接Load加载。加载之后就可以直接实例化他。这里需要强制转型成GameObject类型,这里就用到了之前在枚举的时候不能用到的as方法。

GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;

我创建出来面板后,我么应该把面板放在我们的画布Canvas下面。
所以我们需要得到画布。

    private Transform canvasTransform;
    private Transform CanvasTransform
    {
    
    
        get
        {
    
    
            if (canvasTransform == null)
            {
    
    
                canvasTransform = GameObject.Find("Canvas").transform;
            }
            return canvasTransform;
        }
    }

我们可以通过构造方法的得到,也可以在使用的时候得到,这里我选择了使用的时候得到,定义一个Get方法取得。
这里我们用到了GameObject中的Find方法,因为目前我们的场景中只有一个画布,所以可以直接通过名字查找,同样也可以通过路径去查找。
为什么我们取得画布的Transform类型呢?因为我们要把新实例化的面板放在画布下面,通过Transform组件设置一个父子等级关系。
接下来回到GetPanel方法中。
接下来我们设置父子等级关系,把实例化的面板放在画布的下面。

 instPanel.transform.SetParent(canvasTransform);

SetParent方法有两个参数,第一个是要设置的父类,第二个是是否保持他在世界坐标轴的位置。这里我们是不需要保持的,因为Canvas一般是由一定的缩放比例的,把外界实例化的面板放在Canvas下面,会导致Canvas的缩放比例变得不正常,所以我们第二个参数可以设置false或者不加。
设置好父类我们就可以直接把实例化面板放在字典中,使用Add方法即可。

总结

我们建立好了面板的基类脚本BasePanel,方便以后我们对面板公共功能的设置。
同时我们也设置好了控制UI面板的功能。

猜你喜欢

转载自blog.csdn.net/m0_64058685/article/details/124554091