You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity如何实现反向遮罩并仅让遮罩区域响应点击?

实现不同Canvas下反向遮罩的区域点击限制

核心思路

通过在遮罩Canvas上添加全屏拦截层,仅允许点击圆形遮罩范围内的区域穿透到下方按钮,其余区域直接拦截点击。

具体步骤

1. 调整Canvas层级

确保遮罩Canvas的Sorting Order数值大于按钮所在Canvas,让遮罩显示在按钮上方,优先拦截点击事件。

2. 创建全屏点击拦截层

在遮罩Canvas下新增一个全屏Image(命名为ClickBlocker):

  • 设置Image颜色为你需要的遮罩底色(比如半透黑色),拉伸至覆盖整个屏幕。
  • 开启Raycast Target属性,让它拦截所有点击。
  • 给这个Image挂载自定义脚本TutorialClickFilter。

3. 编写点击过滤脚本

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class TutorialClickFilter : MonoBehaviour, IPointerClickHandler
{
    // 拖拽遮罩里的圆形Image到这里
    public Image circleMaskArea;
    // 可选:直接指定目标按钮,无需射线查找
    public Button targetButton;

    public void OnPointerClick(PointerEventData eventData)
    {
        RectTransform maskRect = circleMaskArea.rectTransform;
        Vector2 localClickPos;
        
        // 把屏幕点击坐标转换为遮罩RectTransform的局部坐标
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            maskRect,
            eventData.position,
            eventData.pressEventCamera,
            out localClickPos);

        // 判断点击是否在圆形范围内
        float clickToCenterDistance = Vector2.Distance(localClickPos, maskRect.rect.center);
        float circleRadius = maskRect.rect.width / 2f;

        if (clickToCenterDistance <= circleRadius)
        {
            // 点击在允许区域,触发目标按钮或穿透点击
            if (targetButton != null)
            {
                targetButton.onClick.Invoke();
            }
            else
            {
                // 自动查找下方Canvas的可点击元素
                foreach (var raycastResult in eventData.raycastResults)
                {
                    // 跳过遮罩Canvas的元素,只处理目标Canvas的交互物
                    if (raycastResult.gameObject.GetComponentInParent<Canvas>() != circleMaskArea.GetComponentInParent<Canvas>())
                    {
                        ExecuteEvents.Execute(raycastResult.gameObject, eventData, ExecuteEvents.pointerClickHandler);
                        break;
                    }
                }
            }
        }
        // 不在允许区域则直接拦截,不做任何处理
    }
}

4. 脚本参数配置

  • 将遮罩Canvas中的圆形遮罩Image拖到脚本的circleMaskArea字段。
  • 若明确知道目标按钮,直接拖到targetButton字段;若需要适配动态场景,保留射线查找逻辑即可。

5. 关闭圆形遮罩的射线检测

确保圆形遮罩Image的Raycast Target属性处于关闭状态,避免它本身拦截点击事件。

特殊场景适配

如果圆形遮罩是非标准正圆(比如自定义形状),可以替换距离判断逻辑:

  • 使用RectTransformUtility.RectangleContainsScreenPoint结合形状边界判断;
  • 读取点击位置的Sprite像素Alpha值,Alpha大于0则视为可点击区域。

内容的提问来源于stack exchange,提问作者Rohit Vishwakarma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:35:29