UI框架从0到1第二节:【全控件适配】把 Toggle、InputField 全都拉进事件系统

在上一节中,我们完成了按钮事件的自动转发------ButtonCustom 会自动向上查找并调用页面的 PanelBase.ProcessEvent(),从而完成"业务逻辑接收"。

但实际项目里我们当然不会只用到 Button,对吧?

Toggle、Slider、InputField、Dropdown......它们都是交互控件,也需要转发事件。

所以本节我们要解决一个关键问题:

❓ 怎么让所有 UI 控件都能使用统一的事件系统,而不是每个都写一套重复逻辑?


🎯 通用方案:抽取公共基类 EventUIBase

所有 UI 控件的事件脚本,其实逻辑大同小异:

  • 初始化时找到上级页面(PanelBase)

  • 在事件触发时转发自己给 PanelBase

因此,我们可以将"向上查找 PanelBase"这段逻辑提取出来,放进一个共同基类 EventUIBase 中。

cs 复制代码
using  UnityEngine;

public  class  EventUIBase : MonoBehaviour
{
	protected  PanelBase  targetPanel;
	
	protected  virtual  void  Init()
	{
		Transform  current = transform;
		while (current != null)
		{
			targetPanel = current.GetComponent<PanelBase>();
			if (targetPanel != null)
			return;
			current = current.parent;
		}
		Debug.LogWarning("No parent with PanelBase found.");
	}
}

✅ 示例:扩展 Button 与 Toggle 的事件脚本

现在我们基于 EventUIBase,轻松地扩展任意控件,只需专注于各自的事件监听绑定即可:

cs 复制代码
using  UnityEngine.UI;
public  class  ButtonCustom : EventUIBase
{
	private  Button  btn;
	
	protected  override  void  Init()
	{
		base.Init();
		btn = GetComponent<Button>();
		btn.onClick.AddListener(() =>
		{
			targetPanel.ProcessEvent(this);
			Debug.Log($"{name} 触发点击事件");
		});
	}
}
cs 复制代码
using  UnityEngine.UI;
public  class  ToggleCustom : EventUIBase
{
	private  Toggle  tog;
	protected  override  void  Init()
	{
		base.Init();
		tog = GetComponent<Toggle>();
		tog.onValueChanged.AddListener((bool  newValue) =>
		{
			targetPanel.ProcessEvent(this);
			Debug.Log($"{name} 触发值变更事件");
		});
	}
}

其他控件(如Slider、Dropdown、InputField)也可仿照上述写法扩展,你只需监听它们自身的变更事件并转发即可。


🧠 面板逻辑:统一处理所有 UI 控件事件

观察上面的代码,你可能会问:

"PanelBase.ProcessEvent() 不是只能接收 ButtonCustom 吗?那 ToggleCustom 怎么进来的?"

这是我们接下来要修改的地方:我们要将 ProcessEvent 改写为泛型方法 ,并且限制只接受继承自 EventUIBase 的对象

这样就能让所有 UI 控件统一走这套通道:

cs 复制代码
public  class  PanelBase : MonoBehaviour
{
	public  void  ProcessEvent<T>(T  eventUI) where  T : EventUIBase
	{
		switch (eventUI.name)
		{
			case  "开始游戏":
				Debug.Log("开始游戏");
			break;
			
			case  "退出游戏":
				Debug.Log("退出游戏");
			break;
			
			default:
				Debug.LogWarning($"未处理的控件事件:{eventUI.name}");
			break;
		}
	}
}

🧩 新问题浮现:脚本挂载仍需手动完成?

虽然现在我们解决了多个控件统一事件处理的问题,但你可能已经意识到:

"我们还是得自己一个个给控件挂上 ButtonCustomToggleCustom,这不还是重复劳动吗?"

没错,这仍然不够自动化,而且一不小心挂错脚本还会导致事件丢失或报错。

所以下一节我们将进入编辑器扩展的世界,写一套"一键挂载 UI 基础脚本"的工具,彻底解放你的右手!

不过提前说一句,下一节不会解决所有控件扩展的逻辑,只是处理自动挂载与类型匹配,核心问题我们将逐步展开。

相关推荐
泉城老铁8 天前
VUE2实现加载Unity3d
前端·vue.js·unity3d
evamango11 天前
《Unity Shader入门精要》十一、让画面动起来
unity3d
Thomas游戏开发11 天前
Unity Android性能优化设置指南
前端框架·unity3d·游戏开发
Thomas游戏开发14 天前
Unity3D C#监听Button点击事件
前端·unity3d·游戏开发
谷宇.16 天前
【Unity3D实例-功能-拔枪】角色拔枪(三)IK的使用-紧握武器
游戏·unity·c#·unity3d·游戏开发·游戏编程·steam
evamango16 天前
《Unity Shader入门精要》十、高级纹理
unity3d
白色牙膏16 天前
从零到搞定:URP Lit彩色箱子材质的开发碎碎念
unity3d
半夜微笑狗18 天前
数据持久化-PlayerPrefs
unity3d
Thomas游戏开发19 天前
博毅创为 Unity_0基础就业班
前端框架·unity3d·游戏开发
谷宇.20 天前
【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
游戏·unity·c#·游戏程序·unity3d·游戏开发·游戏编程