そんな経験はありませんか?インスペクターの AddComponent でアウトラインを追加する場合、そのアルファ値は常に手動で調整する必要があります。
そんな経験はありませんか?比較的大きなフォント サイズのテキストにアウトラインを掛けると、どこにでもストロークが表示されなくなります。
さあ、さあ、今日この 2 つの問題を解決してください。
まずはアウトラインを追加するとき。
Color.a は半分だけである必要があり、手動でフルにプルする必要があります。(なぜいっぱい描かなければならないのかは聞かずに、アートに聞いてください。)
とにかく、私は非常に迷惑です。
それで……
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;
}
}
}
これらの行が何をしているのか説明しましょう。
1.[InitializeOnLoad]
「Unity のロード時、またはスクリプトのロード時に、このプロパティを宣言するすべてのクラスがインスタンス化されます。」
2. ObjectFactory.componentWasAdded += ComponentWasAdded;
は単なるイベントなので、さらに説明する必要があります~
3. ComponentWasAdded (コンポーネント comp)
は非常に単純で、型を判断し、対応するコンポーネントを変更します。(なぜSwitchを使わないのかは聞かないでください。使えるなら使っていたでしょう!)
次に、別の質問があります。
最も一般的な例から始めましょう。
醜い白い角を見ると、不快になります。
Baidu を起動して、すべての偉大な神々がどのようにそれを行うかを確認してください。一般的にはシェーダを使って行います。しかし、第一にそれが理解できず、第二に、なぜそれが有効にならないのか分かりませんでした...
2 つのアウトラインをぶら下げるだけだという記事を見るまでは。
すごいですね、Unity についての私の理解では、アウトラインを使用すると 4 倍の頂点が生成されます。これは、4 つのポイントをコピーし、上下左右に移動して終了しただけだからです。レイヤーを2つ追加すると、5倍×5倍の頂点がそのまま出てきます。
これはおそらく私が今まで見た中で最もとんでもない解決策です...
この時、ふと昔のクラブのことを思い出し、8方向に8を作りました!
頂点の数が 4 倍になりますが、それでも効果は良好であるようです。
それで……
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;
}
}
墨で書いているとは思わないでください。Unity の UI ソースコードでは Shadow を 4 回コピーすることになっています...
簡単に言うと、円を作る必要があるため、0.707f の比率が計算されます。
残りについては、質問しないでください。理解できないことは何もありません。何が理解できないのか...もう一度聞いてください。私はこの作品のソース コードを見ていません。
最後に実際の効果を見てみましょう
、かなり快適になりました。
補足:
会社の上司に聞きましたが、ShaderとOutlineの違いは、Shaderの消費はサンプリング時であり、Outlineは三角形の頂点をコピーすることです。シェーダー サンプリングを 8 回行うことでアウトラインの効果を実現でき、大幅な節約になります。
しかし、悲しいことに、シェーダの方法がわかりません