Unity UI 中最干净的点击区域实现:RaycastZone 完整实战讲解


using UnityEngine;
using UnityEngine.UI;

#if UNITY_EDITOR
using UnityEditor;
#endif

[AddComponentMenu("UI/Raycast Zone")]
public class RaycastZone : MaskableGraphic
{

#if UNITY_EDITOR
    [SerializeField] private bool m_EnableDebugDraw = false;

    [SerializeField] private Color m_DebugColor = new Color(1f, 0f, 0f, 0.2f);
#endif

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();

#if UNITY_EDITOR
        if (!m_EnableDebugDraw)
            return;

        var rect = GetPixelAdjustedRect();
        UIVertex vertex = UIVertex.simpleVert;
        vertex.color = m_DebugColor;

        vertex.position = new Vector2(rect.xMin, rect.yMin);
        vh.AddVert(vertex);

        vertex.position = new Vector2(rect.xMin, rect.yMax);
        vh.AddVert(vertex);

        vertex.position = new Vector2(rect.xMax, rect.yMax);
        vh.AddVert(vertex);

        vertex.position = new Vector2(rect.xMax, rect.yMin);
        vh.AddVert(vertex);

        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
#endif
    }

    protected override void OnPopulateMesh(Mesh mesh)
    {
        mesh.Clear();
    }

#if UNITY_EDITOR
    protected override void OnValidate()
    {
        base.OnValidate();
        SetAllDirty();
    }

    public void SetDebugVisible(bool visible)
    {
        m_EnableDebugDraw = visible;
        SetAllDirty();
    }

    public void SetDebugColor(Color color)
    {
        m_DebugColor = color;
        SetAllDirty();
    }
#endif
}


📘 正文:

✨ 为什么要用 RaycastZone?

在移动 UI 或自定义输入中,常常需要一个看不见但能响应点击的区域。例如:

  • 虚拟摇杆
  • 全屏点击遮罩
  • 引导指引层的“非透明点击区域”

很多开发者习惯用 Image 组件设置透明来处理,但这样仍然会:

✖ 产生 draw call ✖ 增加 fillrate 开销 ✖ 导致 GPU 负担

于是,就有了这类经典实现:继承 MaskableGraphic,但不绘制图像



🧠 RaycastZone 原理

  • MaskableGraphic 本身具有射线检测(RaycastTarget)能力
  • 重写 OnPopulateMesh 清空顶点数据,不渲染图像
  • 保留 raycastTarget,可以照常接收点击事件


✅ 真机无逻辑开销的优化

我们通过 #if UNITY_EDITOR 宏包装调试部分:

  • 编辑器中可开启红色调试绘制
  • 构建到 iOS/Android/WebGL 后调试逻辑完全剔除,连 if 判断都没有


🧪 使用建议

  1. 添加 UI 空物体,附加 RaycastZone.cs
  2. 设置尺寸/锚点,作为你想监听的点击区域
  3. 不要添加 Sprite/Image
  4. 如需调试:勾选 Enable Debug Draw,可设置颜色透明度


🚀 性能对比


方法是否渲染可点击真机性能
Image + Alpha 0✅ 有渲染🟡 有额外 fillrate
RaycastZone❌ 不渲染🟢 零开销,最推荐



Unity SpineManager 系统设计文档

🧱 Spine 材质替换避坑清单(Unity)

评 论