【Unity3D】实现UGUI高亮引导点击

Unity版本2019.4.0f1 Personal <DX11>

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

public class GuideMask : MonoBehaviour, ICanvasRaycastFilter
{
    public Canvas canvas;
    public Transform guideTargetTrans;
    public Image image;
    private Vector3 guideTargetWorldPos;
    private Vector2 lbPos;
    private Vector2 rtPos;
    private Rect rect;

    /// <summary>
    /// ICanvasRaycastFilter接口所实现的方法
    /// </summary>
    /// <param name="sp"></param>
    /// <param name="eventCamera"></param>
    /// <returns></returns>
    public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
    {
        //sp位于屏幕坐标系,(0,0)位于屏幕左下角
        //rect是基于UGUI坐标构建的矩形,UGUI坐标系(0,0)位于屏幕中心, 因此将sp减去一半屏幕宽高得到以屏幕中心为中心点的点
        //简单理解就是sp的中心点是(Screen.width / 2, Screen.height / 2), 实际rect矩形所在坐标系的中心点是(0,0) 故需减去(Screen.width / 2, Screen.height / 2)还原回以(0,0)作为中心点
        //若不转化,不位于同一个坐标系的点和矩形无法进行计算是否处于矩形内。
        Vector2 offsetSp = sp - new Vector2(Screen.width / 2, Screen.height / 2);
        return rect.Contains(offsetSp) ? false : true; //位于矩形内返回false 代表穿透射线, 否则返回true代表正常接收射线

        //穿透射线是指让这个引导黑幕的矩形区域内的射线检测raycast无效化,射线穿透到下一层UGUI 让它下层UI响应点击。
    }

    // Start is called before the first frame update
    void Start()
    {
        guideTargetWorldPos = guideTargetTrans.position;
        //世界转屏幕点
        Vector3 pos = Camera.main.WorldToScreenPoint(guideTargetWorldPos);
        //屏幕点转UGUI坐标系点
        Vector2 localPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), pos, Camera.main, out localPoint);
        lbPos = new Vector2(localPoint.x - 250, localPoint.y - 100);
        rtPos = new Vector2(localPoint.x + 250, localPoint.y + 100);
        //注意:Rect原点是左下角,故需偏移localPoint到左下角传入第一个参数, 第二个参数是Size(矩形右上角是原点左下角+Size得到)
        rect = new Rect(localPoint - new Vector2(250, 100), new Vector2(500, 200));
        Material mat = image.material;
        mat.SetVector("_CustomClipRect", new Vector4(lbPos.x, lbPos.y, rtPos.x, rtPos.y));
    }
}
cs 复制代码
Shader "Hidden/GuideImageEffectShader"
{
    Properties
    {        
        _Color ("Color", Color) = (1,1,1,1)
        _CustomClipRect("CustomClipRect", vector) = (0,0,0,0)
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 screenPosition : TEXCOORD1;
                float4 vertex : SV_POSITION;                
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.screenPosition = v.vertex;
                o.vertex = UnityObjectToClipPos(v.vertex);                
                o.uv = v.uv;
                return o;
            }
            
            float4 _CustomClipRect;
            fixed4 _Color;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = _Color;
                col.a *= (1 - UnityGet2DClipping(i.screenPosition.xy, _CustomClipRect));
                return col;
            }
            ENDCG
        }
    }
}
相关推荐
Felven6 分钟前
A. Ideal Generator
java·数据结构·算法
MoonBit月兔35 分钟前
双周报Vol.70: 运算符重载语义变化、String API 改动、IDE Markdown 格式支持优化...多项更新升级!
ide·算法·哈希算法
How_doyou_do39 分钟前
树状数组底层逻辑探讨 / 模版代码-P3374-P3368
数据结构·算法·树状数组
小鹿鹿啊1 小时前
C语言编程--14.电话号码的字母组合
c语言·开发语言·算法
小O的算法实验室1 小时前
2024年ESWA SCI1区TOP:量子计算蜣螂算法QHDBO,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
C语言魔术师1 小时前
509. 斐波那契数
算法·动态规划
Wendy_robot2 小时前
【前缀和计算和+哈希表查找次数】Leetcode 560. 和为 K 的子数组
c++·算法·leetcode
o独酌o2 小时前
算法习题-力扣446周赛题解
算法·leetcode
一只鱼^_2 小时前
第十六届蓝桥杯大赛软件赛省赛 C/C++ 大学B组 [京津冀]
c语言·数据结构·c++·算法·贪心算法·蓝桥杯·动态规划