【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
        }
    }
}
相关推荐
什仙几秒前
Ansys Maxwell 默认求解器选择
人工智能·笔记·算法·基础·ansys·maxwell
weixin_307779136 分钟前
基于Vosk与CTranslate2的实时语音识别翻译系统 —— 完整C++实现详解
人工智能·算法·自动化·语音识别·原型模式
akarinnnn9 分钟前
深入理解内存函数:原理、应用与优化
c语言·网络·数据结构·算法
一行代码一行诗++17 分钟前
for循环中的break和continue
数据结构·算法
Tisfy21 分钟前
LeetCode 3043.最长公共前缀的长度:哈希表(不转string)
算法·leetcode·散列表·题解·哈希表
代码中介商21 分钟前
排序算法完全指南(三):插入排序深度详解
算法·排序算法
承渊政道25 分钟前
【贪心算法】(经典实战应用解析(六):整数替换、俄罗斯套娃信封问题、可被三整除的最⼤和、距离相等的条形码、重构字符串)
c++·算法·leetcode·贪心算法·排序算法·动态规划·哈希算法
WL_Aurora28 分钟前
Python 算法基础篇之排序算法(二):希尔、快速、归并
python·算法·排序算法
闻缺陷则喜何志丹34 分钟前
【图论 树 启发式合并】P7165 [COCI2020-2021#1] Papričice|普及+
c++·算法·启发式算法·图论··洛谷
alexwang21136 分钟前
AT_abc458_d [ABC458D] Chalkboard Median题解
c++·算法·题解·atcoder