前言

 在Unity开发的游戏和虚拟现实应用中,为了提升用户体验和交互性,我们常常需要对某些物体进行高亮处理,以引导玩家注意或选择特定的目标。然而,Unity引擎本身并未内置这类高亮功能。
 在众多第三方插件中, QuickOutline 以其简洁易用且功能强大的特点脱颖而出。通过多次实践验证,我发现 QuickOutline 不仅能够高效地实现物体高亮的需求,而且其简易性使得初学者也能快速上手。
  QuickOutLine 高亮插件也是我在TapTap的项目过程中了解到的,觉得很好用,故写此篇推荐。


QuickOutLine

首先来介绍一下 QuikOutLine插件。

Unity 的 Quick Outline 是一个轻量级插件,用于快速为 3D 物体添加 描边(Outline) 效果。它通常用于高亮选中物体、交互提示或特殊视觉效果。

核心功能

  • 快速描边:无需编写 Shader,直接通过组件为物体添加描边。
  • 可定制参数
    • 描边颜色(Outline Color
    • 描边宽度(Outline Width
    • 描边模式(基于屏幕空间或几何体膨胀)
  • 性能优化:适合移动端和低配设备(相比一些后处理方案更轻量)。

使用方法

参考文章链接

导入 QuickOutLine 插件之后,在使用时,为需要添加的物体添加 outline 组件即可。

导入
使用

(注!此处可以挂载到所需高亮物体的总物体上,只需要该物体下的子物体中有MaterRenderer组件即可!挂载了Quick Outline插件的组件的模型,都要开启Read/Write Enabled。

功能特性详解

属性

Outline Mode: 高亮方式
Outline Mode

Outline Color:高亮颜色
Outline Width:高亮线的宽度(0-10)
Precompute Outline:用于控制是否在编辑器阶段预先计算物体的轮廓数据。当启用预计算时,轮廓的计算会在编辑器中进行,并将结果与物体一起序列化存储;而当禁用预计算时,轮廓计算则会在运行时的方法中执行。


简单Shader实现

那么有同学问:“煮波煮波有没有不使用插件的方法呢?”,有的兄弟有的,简单的 Unity Shader 就能实现描边效果,以下是我使用过的小例子:

首先我们在Unity资源目录中选择一个位置(建议 /Assests/Shader/ 文件夹),新建一个 outline.shader 文件,这是一个 Unity Shader 文件。然后将以下代码粘贴到shader文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Shader "shader2D/outline"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _lineWidth("lineWidth",Range(0,10)) = 1
        _lineColor("lineColor",Color) = (1,1,1,1)
    }

    // ---------------------------【子着色器】---------------------------
    SubShader
    {
        // 渲染队列采用 透明
        Tags
        {
            "Queue" = "Transparent"
        }

        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            //顶点着色器输入结构体
            struct VertexInput
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            //顶点着色器输出结构体
            struct VertexOutput
            {
               float2 uv : TEXCOORD0;
               float4 vertex : SV_POSITION;
            };

            // ---------------------------【顶点着色器】---------------------------
            VertexOutput vert(VertexInput v)
            {
                VertexOutput o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _lineWidth;
            float4 _lineColor;

            // ---------------------------【片元着色器】---------------------------
            fixed4 frag(VertexOutput i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
               
                // 采样周围4个点
                float2 up_uv = i.uv + float2(0,1) * _lineWidth * _MainTex_TexelSize.xy;
                float2 down_uv = i.uv + float2(0,-1) * _lineWidth * _MainTex_TexelSize.xy;
                float2 left_uv = i.uv + float2(-1,0) * _lineWidth * _MainTex_TexelSize.xy;
                float2 right_uv = i.uv + float2(1,0) * _lineWidth * _MainTex_TexelSize.xy;

                // 如果有一个点透明度为0 说明是边缘
                float w = tex2D(_MainTex,up_uv).a * tex2D(_MainTex,down_uv).a * tex2D(_MainTex,left_uv).a * tex2D(_MainTex,right_uv).a;

                // if(w == 0)
                // {
                //     col.rgb = _lineColor;
                // }
                // 和原图做插值

                col.rgb = lerp(_lineColor,col.rgb,w);
                return col;
            }
            ENDCG
        }
    }
}

这样我们的shader就写好啦,它的核心思路是检测纹理的边缘(Alpha 接近 0 的区域),并用指定的颜色(_lineColor)进行描边。

包含的Properties(属性):

  • _MainTex:主纹理(如 Sprite 图片)。
  • _lineWidth:描边宽度(0~10)。
  • _lineColor:描边颜色(默认白色)。

接下来,我们需要为该shader创建材质。
新建一个材质(Material),然后将材质的shader选为 shader2D/outline

材质配置

创建完成后在需要的地方将材质挂载到目标的 Image 组件的 Material 上。
例如我想让我的卡牌拥有鼠标进入就显示描边的效果,我就控制代码,在使用预制体生成卡牌的时候将 outline 材质挂载到预制体下的 bgImage 组件上。

卡牌预制体

相关代码:

1
2
// 设置bg背景Image的Material
transform.Find("bg").GetComponent<Image>().material = Instantiate(Resources.Load<Material>("Mats/outline"));

到这步就已经万事具备啦,现在只需要写下你需要的代码逻辑,比如我这里就是使用 SetColorSetFloat 在鼠标进入时显示黄色描边,并设置描边宽度为10,鼠标离开后让描边消失:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 鼠标进入
public void OnPointerEnter(PointerEventData eventData)
{
    transform.Find("bg").GetComponent<Image>().material.SetColor("_lineColor", Color.yellow);
    transform.Find("bg").GetComponent<Image>().material.SetFloat("_lineWidth", 10);
}

// 鼠标离开
public void OnPointerExit(PointerEventData eventData)
{
    transform.Find("bg").GetComponent<Image>().material.SetColor("_lineColor", Color.black);
    transform.Find("bg").GetComponent<Image>().material.SetFloat("_lineWidth", 1);
}

运行效果:

尾声

QuickOutLine插件的分享就到这里啦,欢迎在评论区讨论你的见解与推荐!

—end—