Unity UGUI はエレガントな線分を描画します

Unity UGUI はエレガントな線分を描画します

序章

線分を統一して描画する必要がある場合がありますが、最も一般的な方法はLineRendererコンポーネントを使用することです。しかし、時にはLineRendererそれは私たちの使用にはあまり適していません. たとえば、一連の座標変換を通じて、もちろんUIレイヤーに線分を描画する必要がある場合、UIレイヤーで完全にLineRenderer表示はあまり便利ではありません。この時点で、自分で何かを書くことができます。

マスク可能なグラフィック

UI にはこのクラスがあり、そのメソッドをオーバーロードする限りOnPopulateMesh、三角形の面を構築して任意の形状を表現できます。実はよく似ていますMeshFilter主な方法は 2 つあります。

VertexHelper.AddVert			// 添加顶点
VertexHelper.AddTriangle		// 添加三角面

考え方

直線
数学的な意味での線とは異なり、数学では線分は 2 つの端点によって決定されますが、1 つの線分には幅が必要であり、そうでなければ表示できません. 最も基本的な線分には 4 つの頂点が必要であり、2上の図に示すように、3 つのコーナー面。
線分の 2 つの頂点を与えるとき、4 つの頂点を計算することは難しくありません. 線の幅がわかれば、次のようないくつかの方法で簡単に計算できます。

// 首先计算线的方向
Vector2 dir = EndPosition - StartPosition;

// 然后将方向旋转90°。
Vector2 left = (Quaternion.AngleAxis(90, Vector3.forward) * dir).normalized;

// 然后就可以计算出四个顶点:
Vector2 leftBottom = EndPostion + left * HalfLineWidth;
Vector2 rightBottom = EndPostion + ( - Left * HalfLineWidth );
Vector2 leftTop = StartPosition + left * HalfLineWidth;
Vector2 rightTop = StartPosition + ( - left * HalfLineWidth );

しかし、実際に使われる線の多くは直線ではなく、多くの点からなる線です。すると、問題が発生します。
2
上記の計算方法を使用すると、線分が曲がる場所で、2 つの線分の「曲がりの外側」に隙間ができ、「内側」で重なることが避けられません。曲がりの」。この問題をエレガントに解決する方法。
私の考えは、
ここに画像の説明を挿入
上の図に示すように、2 つの線分 (青い点線) の方向をそれぞれ見つけてから、90° 回転して黄色の点線を取得し、平均を計算して、ピンクの実線を取得することです。線分の幅の半分を cos(α) で割ると、エッジの交点が得られます。具体的なコードは次のとおりです。

int count = positions.Count;
int csub1 = count - 1;
for (int i = 0; i < count; ++ i )
{
    
    
	int ia1 = i + 1;
	int is1 = i - 1;
	
	if( i == 0 )
	{
    
    
		// 处理第一个节点
	    FiristPoint(positions[i], positions[ia1], vh);
	}
	else if( i == csub1 )
	{
    
    
		// 处理最后一个节点
	    LastPoint(positions[is1], positions[i], vh);
	}
	else
	{
    
    
		// 处理中间的节点
	    MidPoint(positions[is1], positions[i], positions[ia1], vh);
	}
}

処理の都合上、3つのケースに分けて処理する.最初のノードには先行ノードがなく、最後のノードには後続ノードがない.それを取り出して別々に処理すると、考え方がより明確になる. キーは中間ノードです. 上記のアイデアによると、コードは次のようになります:

/// <summary>
/// 处理中间节点
/// </summary>
/// <param name="prev">上一个顶点</param>
/// <param name="cur">当前顶点</param>
/// <param name="next">下一个顶点</param>
/// <param name="vh">顶点管理器</param>
private void MidPoint(Vector2 prev, Vector2 cur, Vector2 next, VertexHelper vh)
{
    
    
    Vector2 left1 = (orthogonality * (cur - prev)).normalized;
    Vector2 left2 = (orthogonality * (next - cur)).normalized;

    Vector2 left = ((left1 + left2) * 0.5f).normalized;
    float a = Vector2.Angle(left1, left2) * Mathf.Deg2Rad * 0.5f;

    float r = Radius / Mathf.Cos(a);

    vh.AddVert(cur + left * r, color, Vector2.zero);
    vh.AddVert(cur + left * -r, color, Vector2.zero);
}

これで完了です。GUI 上で好きなように線分を作成できます。次のように:

Unity UGUI MaskableGraphic は線分を描画します

改善し続ける

実はまだまだ改善すべき点が多いのですが、上記の土台があれば頭と尻尾のノードを丸頭にしたり、角を大きくしたりと、面白い機能を簡単に拡張できます。ベッセル計算も追加できます。最後に、もちろん頂点ごとに UV を設定することもできます! ! 例では UV が設定されていませんが、実際にはAddVertメソッドは UV 設定をサポートしています。

おすすめ

転載: blog.csdn.net/sdhexu/article/details/126593171