UI框架从0到1第一节:【事件转发起步】让按钮自己“走上来”找逻辑处理

在 UnityUI 开发中,我们经常会遇到这样的烦恼:

  • UI 搭建完毕后,每个按钮都要手动绑定点击事件;

  • 用 Inspector 拖脚本引用不仅繁琐,而且运行时很难排查引用链条

  • 如果 UI 面板一多,手动操作就变得极其低效。

有没有办法写一套脚本框架,实现按钮自动获取 + 自动转发事件,而不是手动一一拖拽绑定?

有的,兄弟,有的,而且代码非常简单。


🎯 第一步:通用按钮脚本

我们先写一个 ButtonCustom 脚本,挂载到任意带有 Button 的物体上,它会自动监听点击事件。

cs 复制代码
using  UnityEngine;
using  UnityEngine.UI;

public  class  ButtonCustom : MonoBehaviour
{
	private  Button  btn;
	private  void  Init()
	{
		btn = GetComponent<Button>();
		btn.onClick.AddListener(() =>
		{ 
			Debug.Log("触发点击事件");
		});
	}
}

通过这种方式,你不需要再手动拖引用到外部管理器,只要挂上这个脚本,就能在点击时响应逻辑。


🤔 问题来了:谁来接收这个按钮事件?

上面的写法只能打印一句调试语句,那如果我们要真正调用逻辑,比如"点击开始游戏"或"点击退出"该怎么办?

答案是:我们要有一个"页面逻辑接收器",专门集中处理 UI 的业务逻辑。

我们定义一个 PanelBase 类,作为每个 UI 页面的逻辑中心:

cs 复制代码
using  UnityEngine;

public  class  PanelBase : MonoBehaviour
{
	public  void  ProcessEvent(ButtonCustom  btn)
	{
		switch (btn.name)
		{
			case  "开始游戏":
				Debug.Log("开始游戏");
			break;
			
			case  "退出游戏":
				Debug.Log("退出游戏");
			break;
			
			default:
				Debug.LogWarning($"未处理的按钮:{btn.name}");
			break;
		}
	}
}

这样,每个按钮在点击时,只要告诉 PanelBase 自己是谁,它就能根据按钮名称处理对应逻辑。


🔁 第二步:按钮转发事件给页面

我们更新一下 ButtonCustom 的逻辑,让它在初始化时向上查找父物体中挂载的 PanelBase,然后把事件转发过去:

cs 复制代码
using  UnityEngine;
using  UnityEngine.UI;

public  class  ButtonCustom : MonoBehaviour
{
	private  Button  btn;
	private  PanelBase  targetPanel;
	
	private  void  Init()
	{
		Transform  current = transform;
		while (current != null)
		{
			targetPanel = current.GetComponent<PanelBase>();
			if (targetPanel != null)
			break;
			current = current.parent;
		}
		if (targetPanel == null)
		{
			Debug.LogWarning("No parent with PanelBase found.");
			return;
		}
		btn = GetComponent<Button>();
		btn.onClick.AddListener(() =>
		{
			targetPanel.ProcessEvent(this);
			Debug.Log($"{name} 触发点击事件");
		});
	}
}

通过这种方式,按钮事件与页面逻辑完全解耦,你不再需要在脚本中显式绑定按钮,只要 UI 节点命名规范、结构正确,就可以完成自动事件转发。


🧩 但问题还没完:只处理 Button 不够

到目前为止,我们的 PanelBase.ProcessEvent() 只能接收 ButtonCustom,那其他控件,比如 Toggle、InputField 呢?

难道我们每种控件都要写一个新的方法?

当然不需要。在下一节中,我们将通过基类继承 + 泛型限制来扩展整个事件转发体系,让 Toggle、InputField 等所有控件都能复用同一套机制。

这才是我们要实现的"通用事件系统"的第一步。

敬请期待第二节内容。

相关推荐
这是我5812 小时前
unity实现梦日记式效果
unity·c#·游戏引擎·unity3d·游戏开发·csharp·c#11.0
kirayoshikake2 天前
UGUI 性能优化系列:第二篇——Canvas 与 UI 元素管理
unity3d
kirayoshikake2 天前
UI框架从0到1第九节:【脚本模板生成】怎么用代码生成代码?
unity3d
kirayoshikake2 天前
Unity入门教程之异步篇第五节:对UniTask的高级封装
unity3d
kirayoshikake2 天前
UI框架从0到1第二节:【全控件适配】把 Toggle、InputField 全都拉进事件系统
unity3d
kirayoshikake2 天前
UI框架从0到1第六节:【轻量 MVVM】用属性驱动 UI,彻底抛弃命令式调用
unity3d
kirayoshikake2 天前
Unity入门教程之异步篇第一节:协程基础扫盲--非 Mono 类如何也能启动协程?
unity3d
kirayoshikake2 天前
响应式编程入门教程第一节:揭秘 UniRx 核心 - ReactiveProperty - 让你的数据动起来!
unity3d
kirayoshikake2 天前
UI框架从0到1第五节:【事件消息体】不仅知道你点了啥,还知道你改了啥
unity3d
kirayoshikake2 天前
响应式编程入门教程第六节:进阶?Combine、Merge、SelectMany 与错误处理
unity3d