关于unity的UI模块封装代码

关于UI模块的封装
UI流程
1、先会由美术给一个效果图
2、然后美术将效果图切成碎图
3、程序拿到碎图后打成大图,基本都是使用TexturePacker来进行操作,一般都是用的png格式,然后选择的是RGBA4通道,RGB是红绿蓝通道,A则是透明通道,JPG则没有透明通道。(RGBA8888:每个通道占8bit ,8bit=1byte,1024byte=1k,1024k=1M,1024M=1T,1024T=1Pb。)其中设置图片大小:兼容所有机器一般只需要10241024,一般的中高端机则需要20482048
4、接下来就是拼UI了,拼UI的第一步就是先要把做一个panel,然后把UI的原图拖上去,将透明度调低,以此来进行无缝的拼接,注意一定要将层级分好。总结下来就是以Panel为单位,考虑界面分层。
在这里插入图片描述

5、然后才是写代码MCV,M是数据模型,V是界面,C是逻辑控制器

在这里插入图片描述

其中子控件要主动上报:
1、我们就给任何一个子控件都挂上一下UIBehaviour,
2、使UIBehaviour注册到UIManager上

那么UIManager又应该怎么保存注册的子控件呢!
以上图为例,我们以panel为单位,panel下面又管理了很多的子控件

废话不多说,下面上代码

public class UIManager : MonoBehaviour
{
    public static UIManager Instance;//单例模式
    Dictionary<string, Dictionary<string, GameObject>> allWedgate;//字典类型,如上图那样的树形结构
    private void Awake()
    {
        Instance = this;//赋值
        allWedgate = new Dictionary<string, Dictionary<string, GameObject>>();//实例化
    }
    public void RegistGameObject(string panleName,string wedgateName,GameObject obj)//注册
    {
      
        if(!allWedgate .ContainsKey(panleName))//so the dictionary had not panle object that create one;
        {
            allWedgate[panleName] = new Dictionary<string, GameObject> ();
        }
        allWedgate[panleName].Add(wedgateName ,obj);
    }
    public GameObject GetGameObject(string panleName,string wedgateName)//获取物体
    {
        if(allWedgate [panleName]!=null)
        {
            return allWedgate[panleName][wedgateName];
        }
        return null;
    }
  
}

using UnityEngine.UI;
using UnityEngine.Events;
/// <summary>
/// 挂载到panle上的
/// </summary>
public class UIBase : MonoBehaviour
{
    
    private void Awake()
    {
        Transform[] allChildren = transform.GetComponentsInChildren <Transform> ();//获取孩子们的Transfrom
        for (int i = 0; i < allChildren.Length; i++)
        {
           if( allChildren[i].name.EndsWith ("_N"))//结尾为_N就是我们要用到的组件
            {
                allChildren[i].gameObject.AddComponent<UIBehaviour >();//添加UIBehaviour组件
            }
        }
    }
    public GameObject GetGameObject(string wedgateName)//获取对应的ui物体
    {
         
       GameObject tmpGameObject=  UIManager.Instance.GetGameObject(transform .name ,wedgateName);
        if(tmpGameObject !=null)
        {
            return tmpGameObject;
        }
        return null;
    }

    public UIBehaviour GetUIBehaviour(string wedgateName)//获取对应的UIBehaviour
    {
        UIBehaviour  tmpUIBehaviour= GetGameObject(wedgateName).GetComponent <UIBehaviour >();
        if(tmpUIBehaviour != null)
        {
            return tmpUIBehaviour; 
        }
        return null;
    }

    public void AddButtonListen(string wedgateName,UnityAction action)//Button监听事件
    {
        UIBehaviour tmpBehaviour = GetUIBehaviour(wedgateName);
        if(tmpBehaviour !=null)
        {
            tmpBehaviour.AddButtonListen(action);
        }
    }
    public void ChangeTextContent(string wedgateName,string content)//文本改变
    {

        UIBehaviour tmpBehaviour = GetUIBehaviour(wedgateName);
        if (tmpBehaviour != null)
        {
            tmpBehaviour.ChangeTextContent (content);
        }
    }
}


using UnityEngine.UI;
using UnityEngine.Events;

public class UIBehaviour : MonoBehaviour
{
    private void Awake()
    {
        UIBase uiBase = transform.GetComponentInParent<UIBase>();//找到上层的panle
        UIManager.Instance.RegistGameObject(uiBase .name ,transform .name ,gameObject );//在UIManager里面注册
    }


    public void AddButtonListen(UnityAction action)//Button监听事件
    {
        Button tmpButton = transform.GetComponent<Button>();
        if(tmpButton !=null)
        {
            tmpButton.onClick.AddListener(action);
        }
    }
    public void AddSliderListen(UnityAction<float> action)//Slider监听事件
    {
        Slider tmpSlider = transform.GetComponent<Slider>();
        if (tmpSlider != null)
        {
            tmpSlider.onValueChanged .AddListener(action);
        }
    }
    public void AddInputFieldEndEditorListen(UnityAction<string> action)//输入框编辑结束
    {
        InputField tmpInputField = transform.GetComponent<InputField>();
        if (tmpInputField != null)
        {
            tmpInputField.onEndEdit .AddListener(action);
        }
    }
    public void AddInputFieldonValueChangeListen(UnityAction<string> action)//输入框内容改变
    {
        InputField tmpInputField = transform.GetComponent<InputField>();
        if (tmpInputField != null)
        {
            tmpInputField.onValueChanged .AddListener(action);
        }
    }
    public void ChangeTextContent(string content)//文本内容改变
    {
        Text tmpText = transform.GetComponent<Text>();
        if (tmpText != null)
        {
            tmpText.text=content;
        }
    }
    public void ChangeImageSprite(Sprite name)//图片精灵更改
    {
        Image tmpImage = transform.GetComponent<Image>();
        if (tmpImage != null)
        {
            tmpImage.sprite = name;
        }
    }
}


public class UIUse : UIBase
{
    public void  OnClick()
    {
        Debug.Log("点击成功!");
    }
    // Start is called before the first frame update
    void Start()
    {
        AddButtonListen("Button_N",OnClick);//增加ButtonListener
        ChangeTextContent("Text_N","100,you are my heart! ");//文本改变
}
}

在这里插入图片描述
这样UI里面可以这样排列,你会发现里面的image没有挂载UIBehaviour组件,
而Button_N则多出这个组件,点击之后会是如下图
在这里插入图片描述
其中的Text_N的显示内容如下
在这里插入图片描述
最后一定要记住对于这些代码一定要分好层级
最好是每层代码都分成M层和C层

如同下面的注册代码一样

public class RegistModle//数据层
{
    public string password;
    public string userName;
}

public class RegistLogic//逻辑层
{
    public void OnClick()
    {
        Debug.Log("点击成功!");
    }
}

public class Regist :UIBase 
{

    RegistLogic registLogic = new RegistLogic();
    // Start is called before the first frame update
    void Start()
    {
        AddButtonListen("Button_N", registLogic.OnClick);//增加ButtonListener

    }
}

这样的话,在进行修改的时候,就可以只修改一层里面的,其他层的就不用修改了
不要害怕类写得多,要尽量的进行拆分,当你的每个类的代码不超过200行的时候
,你的架构思想也就成型了。

还有就是上面的这个UI模块需要注意以下几点
1、不同的panle的名字不能一样
2、同一个panle下我们要使用的组件的名字不能一样
3、不同的panle下的我们要使用的组件的名字可以一样

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值