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

Unity3d UGUI图片按钮只有非透明区域(透明阈值)可以点击功能实现(含源码)

前言

在Unity有小地图相关功能场景下,经常有需要点击范围检测的功能,特别是游戏地图界面的精确交互往往是决定玩家体验的关键因素。传统矩形按钮的碰撞检测在复杂地形场景中暴露了显著缺陷:当玩家点击河流、山脉边缘或迷雾区域时,本应无效的地形区域却意外触发了交互会导致地形穿透、视觉误导等问题。
透明阈值点击检测正是解决地图交互的好方案。实现通过像素级Alpha通道分析,将地图覆盖的可点击区域镂空,即可屏蔽不可点击区域。通过设置 Image.alphaHitTestMinimumThreshold 属性,使按钮只响应图像中不透明度高于设定阈值的区域(忽略透明部分)。

实现

核心思想就是UGUI图片组件的alphaHitTestMinimumThreshold 属性控制各区域的点击。

地图UI

这里以地图UI为例,以以下的游戏地图为小地图:
在这里插入图片描述

随意创建一个图层覆盖其之上,将可以点击区域镂空:
在这里插入图片描述

两个地图图层叠加效果如下:
在这里插入图片描述

并将覆盖层图片添加Button,只要输出点击状态即可。
图片需要
图片的 Read/Write Enabled 必须开启(在纹理导入设置中)
在这里插入图片描述

纹理格式需支持透明度(如 PNG)
如果不启用会报错:

Using alphaHitTestMinimumThreshold greater than 0 on Image whose sprite texture cannot be read. Texture ‘***_cover’ is not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings. Also make sure to
disable sprite packing for this sprite.

编码

直接设置属性代码:

using UnityEngine;
using UnityEngine.UI;[RequireComponent(typeof(Image))]
public class AlphaButton : MonoBehaviour
{[Header("透明度阈值设置")][Tooltip("值越小越敏感,推荐0.05-0.3")][Range(0f, 1f)]public float alphaThreshold = 0.1f;void Start(){ApplyAlphaThreshold();}void OnValidate(){// 在编辑器模式下实时预览效果if (Application.isPlaying){ApplyAlphaThreshold();}}private void ApplyAlphaThreshold(){var image = GetComponent<Image>();if (image != null){image.alphaHitTestMinimumThreshold = alphaThreshold;}}
} 

将脚本挂载到 UI Button 对象上,在 Inspector 中调整 alphaThreshold(推荐 0.05-0.3)
确保按钮图片的纹理设置正确(Read/Write Enabled = true)否则会报错。

这里应该是完成了功能,不过测试发现有时候是失效的,最后发现需要设置Mesh Type 为 Full Rect。
在这里插入图片描述

所以修改了代码,加入检测图片的设置并提醒:

using UnityEngine;
using UnityEngine.UI;[RequireComponent(typeof(Image))]
public class AlphaButton : MonoBehaviour
{[Header("透明度阈值设置")][Tooltip("值越小越敏感,推荐0.05-0.3")][Range(0f, 1f)]public float alphaThreshold = 0.1f;void Start(){ApplyAlphaThreshold();}void OnValidate(){// 在编辑器模式下实时预览效果if (Application.isPlaying){ApplyAlphaThreshold();}}private void ApplyAlphaThreshold(){var image = GetComponent<Image>();if (image == null) return;// 检测精灵是否存在if (image.sprite == null){Debug.LogError("AlphaButton: 未找到精灵图片!", this);return;}// 检测Mesh Type是否为Full Rectif (image.sprite.meshType != SpriteMeshType.FullRect){Debug.LogError($"AlphaButton: 精灵 '{image.sprite.name}' 的Mesh Type应为Full Rect! " +$"当前类型: {image.sprite.meshType}", this);return;}// 检测纹理是否可读if (!image.sprite.texture.isReadable){Debug.LogError($"AlphaButton: 纹理 '{image.sprite.texture.name}' 未开启Read/Write Enabled! " +"请在导入设置中启用", this);return;}// 应用透明度阈值image.alphaHitTestMinimumThreshold = alphaThreshold;}
}

这里有一种说法是网格类型(如 Tight)会使用简化网格碰撞体,简化网格会破坏透明度检测的准确性。

其他

性能影响:透明度检测会增加计算开销,避免在大量按钮上使用。

http://www.dtcms.com/a/329900.html

相关文章:

  • OSG —— Windows11下Vs2017完美编译Osg3.6.5+osgQt(附:Osg+osgQt测试用例)
  • GLSL学习
  • IPO辅导四年半,马上消费何时“马到成功”?
  • 深度解析:DCF估值模型实战指南 ——以Kappa Pi Therapeutics为例的完整估值建模过程
  • 万字长文全解析:五种主流归一化方法深入讲解(BN/LN/IN/GN/WN)
  • html img标签设置默认图片,防止图片路径不存在导致图片不展示影响页面美观
  • 微服务单元测试组件
  • 二分|回溯
  • 了解 Linux 中的 /usr 目录以及 bin、sbin 和 lib 的演变
  • C++算法·递推递归
  • 基于.Net Framework4.5 Web API 引用Swagger
  • HCIP——OSPF综合实验
  • 药房智能盘库系统:基于CV与时间序列预测的库存革命
  • 蓝蜂网关在雄安新区物联网建设中的关键应用
  • Vue内置组件全解析:从入门到面试通关
  • 用 OPC UA C# WinForm 的单节点订阅方法
  • 【个人项目】跑者天地—测试用例
  • AI搜索的极限优化、新兴技术、硬件加速、特定行业解决方案
  • [QtADS]解析demo.pro
  • 利用 Makefile 高效启动 VIVADO 软件:深入解析与实践
  • 十,算法-动态规划
  • 深入理解 Cookie 与 Session —— Web 状态保持详解与实战
  • 目标检测公开数据集全解析:从经典到前沿
  • Linux软件编程3.(文件IO和目录IO)
  • windows设置相对路径的快捷方式
  • 想要PDF翻译保留格式?用对工具是关键
  • h5bench(4)
  • MySQL——binlog刷盘机制
  • django name ‘QueryDict‘ is not defined
  • POST 请求内容类型