はじめに
前回、三角メッシュを描画しました
uGUIで線を引く~その1:三角メッシュの描画
今回は、それを応用して、四角を作成します
作ってみる
前回は頂点3つでしたが、4つ用意して、メッシュを2つ描画するだけです
using UnityEngine;
using UnityEngine.UI;
// ↓ugui描画に必須なコンポーネント達
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(RectTransform))]
public class UIOneLine : Graphic
{
/// <summary>
/// uGUIでメッシュ生成する際のコールバック
/// </summary>
/// <param name="vh">この引数にメッシュを設定していく</param>
protected override void OnPopulateMesh(VertexHelper vh)
{
//(1)座標の準備
var v1 = new Vector2(0.0f, 0.0f);
var v2 = new Vector2(100.0f, 0.0f);
var v3 = new Vector2(0.0f, 100.0f);
var v4 = new Vector2(100.0f, 100.0f);
// (2)(1)の座標に頂点を追加
AddVert(vh, v1);
AddVert(vh, v2);
AddVert(vh, v3);
AddVert(vh, v4);
// (3)(2)で追加した頂点に三角形メッシュを2つ設定
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(1, 2, 3);
}
private void AddVert(VertexHelper vh, Vector2 pos)
{
var vert = UIVertex.simpleVert;
vert.position = pos;
vert.color = color;
vh.AddVert(vert);
}
}
(1)のv3,v4のy座標100.0f
を、5.0fにすれば
線になりました!
実用性をあげる
インスペクターで設定できるようにします。
ただ、線を引くのにいちいち4点を指定するのは面倒なので、2点と太さをもらって、描画するようにしてみます。
using UnityEngine;
using UnityEngine.UI;
// ↓ugui描画に必須なコンポーネント達
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(RectTransform))]
public class UIOneLine : Graphic
{
[SerializeField]
private Vector2 _position1;
[SerializeField]
private Vector2 _position2;
[SerializeField]
private float _weight; // ←太さ
protected override void OnPopulateMesh(VertexHelper vh)
{
// (1)頂点を頂点リストに追加
AddVert(vh, new Vector2(_position1.x, _position1.y - _weight / 2));
AddVert(vh, new Vector2(_position1.x, _position1.y + _weight / 2));
AddVert(vh, new Vector2(_position2.x, _position2.y - _weight / 2));
AddVert(vh, new Vector2(_position2.x, _position2.y + _weight / 2));
// (2)頂点リストを元にメッシュを貼る
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(1, 2, 3);
}
private void AddVert(VertexHelper vh, Vector2 pos)
{
var vert = UIVertex.simpleVert;
vert.position = pos;
vert.color = color;
vh.AddVert(vert);
}
}
できました!
…が、ここで問題が。。
#線を動的に動かしたい
上記の例だと、プレイ前に設定した位置に線が引かれますが、プレイ中にインスペクターでPosition1とPosition2を変更しても、線が変わりません。
なぜかというと、確かに、変更したタイミングで再度OnPopulateMeshが呼ばれて、変更後の座標に頂点が増えますが、メッシュは、変更前の座標のインデックス(0,1,2,3)に描画しているため、変更後の座標にメッシュが描画していないためです。
じゃあどうすればいいかというと、行頭でClearメソッドを呼んで、同インデックスの頂点の座標を更新するようにします
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(RectTransform))]
public class UIOneLine : Graphic
{
[SerializeField]
private Vector2 _position1;
[SerializeField]
private Vector2 _position2;
[SerializeField]
private float _weight;
protected override void OnPopulateMesh(VertexHelper vh)
{
// (1)☆この行を追加!!過去にAddした頂点を全部削除!
vh.Clear();
// (2)あとは同じ。頂点を頂点リストに追加
AddVert(vh, new Vector2(_position1.x, _position1.y - _weight / 2));
AddVert(vh, new Vector2(_position1.x, _position1.y + _weight / 2));
AddVert(vh, new Vector2(_position2.x, _position2.y - _weight / 2));
AddVert(vh, new Vector2(_position2.x, _position2.y + _weight / 2));
// (3)頂点リストを元にメッシュを貼る
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(1, 2, 3);
}
private void AddVert(VertexHelper vh, Vector2 pos)
{
var vert = UIVertex.simpleVert;
vert.position = pos;
vert.color = color;
vh.AddVert(vert);
}
}
次回予告
このままだと、太さが縦への長さにしているため、縦に線が引けません。
次は、線の角度によって、4頂点の位置を調整するようにします
uGUIで線を引く~その3:線の端を垂線にする~