当前位置: 首页 > web >正文

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

RaycastZone可以解决什么问题

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

虚拟摇杆
全屏点击遮罩
引导指引层的“非透明点击区域”
很多开发者习惯用 Image 组件设置透明来处理,但这样仍然会:

  1. 产生 draw call
  2. 增加 fillrate 开销
  3. 导致 GPU 负担

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

RaycastZone 原理

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

真机无逻辑开销的优化
我们通过 #if UNITY_EDITOR 宏包装调试部分:

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

性能对比

方法是否渲染可点击真机性能
Image + Alpha 0有渲染有额外 fillrate
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);
#endifprotected override void OnPopulateMesh(VertexHelper vh){vh.Clear();#if UNITY_EDITORif (!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_EDITORprotected 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
}

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

http://www.xdnf.cn/news/20549.html

相关文章:

  • Knex 和 Schema 是什么?
  • 从 “Hello AI” 到企业级应用:Spring AI 如何重塑 Java 生态的 AI 开发
  • 像素图生成小程序开发全解析:从图片上传到Excel图纸
  • Spring Cloud Alibaba快速入门02-Nacos(上)
  • java社交小程序源码支持APP多端springboot部署与功能模块详解
  • *和->的区别
  • FC平台安装Windows Server2016并连接V6存储
  • C++并发编程指南 std::async 介绍使用
  • 使用 n8n 结合通义千问大模型构建业务数据库分析智能体
  • %前置模糊查询优化
  • shell脚本作业
  • 4.6 多个光源
  • 【数论】P10580 [蓝桥杯 2024 国 A] gcd 与 lcm|普及+
  • MapStruct详解
  • Linux RCU (Read-Copy-Update) 机制深度分析
  • leetcode 912 排序数组(快速排序)
  • 【CV】Opencv图像处理——①几何变换 (1)
  • 神马 M66S+ 282T矿机参数详解:SHA-256算法与Hydro冷却技术
  • 贪心算法应用:食品生产线排序问题详解
  • 继承详解(c++)
  • langchain源码概览
  • Java全栈开发面试实录:从基础到实战的深度解析
  • 【牛客刷题-剑指Offer】BM18 二维数组中的查找:一题四解,从暴力到最优
  • Python元组:不可变但灵活的数据容器
  • LwIP入门实战 — 3 以太网外设 (ETH)
  • 什么是JQ
  • solidity函数篇2
  • Netty从0到1系列之EventLoop
  • 魅族 Note 16 解锁 BL 及 Root 官方刷机包下载Flyme 12.0.1.5A 型号 M521Q
  • 基于SVN搭建企业内部知识库系统实践