Unity makes a Circle Outline that consumes a lot of money but has a better effect

Have you ever had such an experience? When you add an Outline in the Inspector's AddComponent, its Alpha value will always need to be adjusted manually.
Have you ever had such an experience? When you hang Outline on a Text with a relatively large font size, it does not have strokes everywhere.

Come, come, solve these two problems today.

First of all, when you add an Outline.
insert image description here
Color.a must be only half, and must be manually pulled to full. (Don't ask me why I have to draw to full, ask the art.)
Anyway, I am very annoying.

so……
insert image description here

using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

[InitializeOnLoad]
public class ObjectFactoryManager
{
    
    
    static ObjectFactoryManager()
    {
    
    
        ObjectFactory.componentWasAdded += ComponentWasAdded;
    }

    private static void ComponentWasAdded(Component comp)
    {
    
    
        if (comp.GetType() == typeof(Image))
        {
    
    
            Image image = (Image)comp;
            image.raycastTarget = false;
        }
        else if (comp.GetType() == typeof(Outline) || comp.GetType() == typeof(CircleOutline))
        {
    
    
            Outline outline = (Outline)comp;
            Color effectColor = outline.effectColor;
            effectColor.a = 1f;
            outline.effectColor = effectColor;
        }
    }
}

Let me explain what these lines are doing.
1.[InitializeOnLoad]
insert image description here
"When Unity loads or when your script loads, all classes that declare this property will be instantiated".
2. ObjectFactory.componentWasAdded += ComponentWasAdded;
is just an event, so need to say more~
3. ComponentWasAdded (Component comp)
is very straightforward, it is to judge the type, and then modify the corresponding component. (Don't ask me why I don't use Switch, if it can be used, I would have used it!)

Then there is another question.
Let’s start with the most common example:
insert image description here
looking at the ugly white corners, it’s uncomfortable.
Start Baidu to see how all the great gods do it. Generally speaking, it is done with shader. But, firstly, I couldn’t understand it, and secondly, I didn’t know why it didn’t take effect...
until I saw an article saying that just hang two outlines.
Awesome, in my understanding of Unity, using an Outline will generate 4 times more vertices, because he just copied 4 points, and then moved up, down, left, and right to finish. With the addition of two layers, the vertices of 5 times by 5 times will come out directly.
This is probably the most outrageous solution I've ever seen...

At this moment, I suddenly remembered what my old club did, and made 8 in 8 directions!
It seems to work, although it will quadruple the number of vertices, but the effect is still good.

so……
insert image description here

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CircleOutline : Outline
{
    
    
    //斜向圆形折扣比例
    private readonly float diagonalRotia = 0.707f;

    public override void ModifyMesh(VertexHelper vh)
    {
    
    
        if (!IsActive())
            return;

        List<UIVertex> verts = new List<UIVertex>();
        vh.GetUIVertexStream(verts);

        //改变偏移数据生成8倍的顶点数据
        int start = 0;
        int end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, effectDistance.x * diagonalRotia, effectDistance.y * diagonalRotia);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, effectDistance.x, 0);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, effectDistance.x * diagonalRotia, -effectDistance.y * diagonalRotia);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, 0, -effectDistance.y);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, -effectDistance.x * diagonalRotia, -effectDistance.y * diagonalRotia);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, -effectDistance.x, 0);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, -effectDistance.x * diagonalRotia, effectDistance.y * diagonalRotia);

        start = end;
        end = verts.Count;
        ApplyShadow(verts, effectColor, start, verts.Count, 0, effectDistance.y);

        //重添加到原始数据中
        vh.Clear();
        vh.AddUIVertexTriangleStream(verts);

        //清理
        verts.Clear();
        verts = null;
    }
}

Don’t think I’m writing in ink, Unity’s UI source code is to copy Shadow four times...
To put it simply, the ratio of 0.707f is calculated because of the need to make a circle.
For the rest, don’t ask, there’s nothing you don’t understand, what you don’t understand... Just ask me again, I haven’t looked at the source code of this piece.

Finally, look at the actual effect
insert image description here
. Well, it is much more comfortable.

insert image description here
Supplement:
I asked the boss of the company. The difference between using Shader and Outline is that the consumption of shader is on sampling, and the outline is to copy the vertices of the triangle. Shader sampling 8 times can achieve the effect of my outline, which saves a lot.
However, I just don’t know how to shader, alas

Guess you like

Origin blog.csdn.net/qql7267/article/details/109602513