在U3D游戏开发中,我们常常使用UI逻辑,对于大量的UI逻辑,我们会选择构建UI面板基类,让所有面板UI继承,从而减少代码量,今天我将介绍关于UI面板基类框架搭建的代码思路。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 面板基类
/// 帮助我门通过代码快速的找到所有的子控件
/// 方便我们在子类中处理逻辑
/// 节约找控件的工作量
/// </summary>
public class BasePanel : MonoBehaviour
{
//整体控制淡入淡出的画布组件
private CanvasGroup canvasGroup;
//淡入淡出的速度
private float alphaSpeed = 8;
//是否一开始要显示
private bool isShow;
//淡出成功执行的委托函数
// private UnityAction hideCallBack;
//通过里式转换原则 来存储所有的控件
private Dictionary<string, List<UIBehaviour>> controlDic = new Dictionary<string, List<UIBehaviour>>();
// Use this for initialization
protected virtual void Awake () {
FindChildrenControl<Button>();
FindChildrenControl<Image>();
FindChildrenControl<Text>();
FindChildrenControl<Toggle>();
FindChildrenControl<Slider>();
FindChildrenControl<ScrollRect>();
FindChildrenControl<InputField>();
//test
//从一开始获取面板上面挂载的组件 如果没有就通过代码添加
canvasGroup=this.GetComponent<CanvasGroup>();
if(canvasGroup==null)
canvasGroup=this.gameObject.AddComponent<CanvasGroup>();
}
/// <summary>
/// 显示自己
/// </summary>
public virtual void ShowMe()
{
//test
isShow=true;
canvasGroup.alpha = 0;
}
/// <summary>
/// 隐藏自己
/// </summary>
public virtual void HideMe()
{
//test
isShow = false;
canvasGroup.alpha = 1;
//记录传入淡出成功会执行的函数
// hideCallBack=callBack;
}
protected virtual void OnClick(string btnName)
{
}
protected virtual void OnValueChanged(string toggleName, bool value)
{
}
protected virtual void Update()
{
if ((canvasGroup==null))
{
return;
}
//淡入
if (isShow&&canvasGroup.alpha!=1)
{
canvasGroup.alpha += alphaSpeed * Time.deltaTime;
if(canvasGroup.alpha>=1)
canvasGroup.alpha = 1;
}
//淡出
else if(!isShow)
{
canvasGroup.alpha -= alphaSpeed * Time.deltaTime;
if(canvasGroup.alpha<=0)
{
canvasGroup.alpha=0;
// hideCallBack?.Invoke();
}
}
}
/// <summary>
/// 得到对应名字的对应控件脚本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="controlName"></param>
/// <returns></returns>
protected T GetControl<T>(string controlName) where T : UIBehaviour
{
if(controlDic.ContainsKey(controlName))
{
for( int i = 0; i <controlDic[controlName].Count; ++i )
{
if (controlDic[controlName][i] is T)
return controlDic[controlName][i] as T;
}
}
return null;
}
/// <summary>
/// 找到子对象的对应控件
/// </summary>
/// <typeparam name="T"></typeparam>
private void FindChildrenControl<T>() where T:UIBehaviour
{
T[] controls = this.GetComponentsInChildren<T>();
for (int i = 0; i < controls.Length; ++i)
{
string objName = controls[i].gameObject.name;
if (controlDic.ContainsKey(objName))
controlDic[objName].Add(controls[i]);
else
controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
//如果是按钮控件
if(controls[i] is Button)
{
(controls[i] as Button).onClick.AddListener(()=>
{
OnClick(objName);
});
}
//如果是单选框或者多选框
else if(controls[i] is Toggle)
{
(controls[i] as Toggle).onValueChanged.AddListener((value) =>
{
OnValueChanged(objName, value);
});
}
}
}
}
对于大量UI使用的工程当中,存在大量UI时,我们会考虑代码查找的方式获取UI,防止UI数量过多,拖拽麻烦甚至关联出错,以上提供查找UI的代码思路。
对于UI面板我们对其进行了淡入淡出的代码处理,其中淡入淡出的参数可以自行调整。需要注意的是,对于你的面板使用了Update方法的,一定要重写其方法并且继承保留父类的方法,否则根据父类逻辑,你的UI面板显示都是alpha为0,(即:创建面板,但是你无法看见其显示)
需要注意的是,如果你的UI组件(例如:背包中的格子,商店中的单个商品小组件)使用继承了该面板基类,需要在Start或者Awake方法中移出CavasGroup组件,防止商品不显示(商品可以会快速显示然后隐藏)。使用我以上的源代码,对于UI小组件就需要代码移出canvasgroup组件。
(以上代码适用于UGUI)
希望我的思路对你们有所帮助,喜欢就点赞收藏吧!