💡 【Unity UGUI】Maskを使わずに実現する「穴あき」ハイライト演出
📌 この記事は Zenn に投稿した内容のアーカイブです。 はじめに UGUIで部分的にハイライトを当てたい場面、特にチュートリアル中の誘導UI では「特定のボタンだけを明るく見せ、他の部分を半透明で覆う」演出がよく使われます。 一般的には Mask や RectMask2D を利用しますが、これらにはいくつかの課題があります。 Mask :Stencilバッファを使うため、描画コストが高い RectMask2D :矩形領域しか扱えず、穴あき表現(逆マスク) はできない そこで今回は、MaskableGraphic を継承し、完全プログラム制御で「逆マスク(穴あきマスク)」を生成する方法 を紹介します。 最終的には、ハイライト部分がクリック可能で、他の部分はブロックされる 、高性能な HollowOutMask コンポーネントを実装していきます。 目標仕様 機能 説明 視覚効果 自身の RectTransform 領域内に半透明のマスクを描画し、指定の RectTransform 部分を「くり抜く」 射線処理 穴の部分はクリックが通過 し、マスク部分はクリックをブロック 動的追従 対象オブジェクトが動いたりスケールが変化しても、くり抜き領域が追従 これを、Mask 系コンポーネントを使わずに、頂点操作 だけで実現します。 実装の基本構造 HollowOutMask は MaskableGraphic を継承し、OnPopulateMesh() をオーバーライドします。 頂点生成の考え方 想像してみてください。 マスク全体を表す「外側の矩形(Outer Rect)」と、くり抜く「内側の矩形(Inner Rect)」があるとします。 この2つの矩形を組み合わせ、外側を塗りつつ内側を抜くには、8つの頂点 と8枚の三角形 が必要です。 コード例:OnPopulateMesh() protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (_isTargetNull) { base.OnPopulateMesh(vh); return; } // Outer Rect(自身のRectTransform基準) float outerLx = rectTransform.rect.xMin; float outerBy = rectTransform.rect.yMin; float outerRx = rectTransform.rect.xMax; float outerTy = rectTransform.rect.yMax; vh.AddVert(new Vector3(outerLx, outerTy), color, Vector2.zero); vh.AddVert(new Vector3(outerRx, outerTy), color, Vector2.zero); vh.AddVert(new Vector3(outerRx, outerBy), color, Vector2.zero); vh.AddVert(new Vector3(outerLx, outerBy), color, Vector2.zero); // Inner Rect(穴部分) float innerLx = _targetMin.x; float innerBy = _targetMin.y; float innerRx = _targetMax.x; float innerTy = _targetMax.y; vh.AddVert(new Vector3(innerLx, innerTy), color, Vector2.zero); vh.AddVert(new Vector3(innerRx, innerTy), color, Vector2.zero); vh.AddVert(new Vector3(innerRx, innerBy), color, Vector2.zero); vh.AddVert(new Vector3(innerLx, innerBy), color, Vector2.zero); // Triangles(外側と内側の間を埋める) vh.AddTriangle(0, 1, 5); vh.AddTriangle(5, 4, 0); vh.AddTriangle(1, 2, 6); vh.AddTriangle(6, 5, 1); vh.AddTriangle(2, 3, 7); vh.AddTriangle(7, 6, 2); vh.AddTriangle(3, 0, 4); vh.AddTriangle(4, 7, 3); } これで、中央が透明な「リング状ポリゴン を生成できます。 ...