LoginSignup
6
4

uGUIで線を引く~その2:線の描画編~

Last updated at Posted at 2019-12-29

はじめに

前回、三角メッシュを描画しました
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);
    }
}

image.png
(1)のv3,v4のy座標100.0fを、5.0fにすれば
image.png
線になりました!

実用性をあげる

インスペクターで設定できるようにします。
ただ、線を引くのにいちいち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);
    }
}

image.png
できました!
…が、ここで問題が。。
#線を動的に動かしたい
上記の例だと、プレイ前に設定した位置に線が引かれますが、プレイ中にインスペクターで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);
    }
}

MoveOneLine.gif

ちなみに再生してなくても動かせます。便利!
MoveOneLineInEditor.gif

次回予告

このままだと、太さが縦への長さにしているため、縦に線が引けません。
次は、線の角度によって、4頂点の位置を調整するようにします
uGUIで線を引く~その3:線の端を垂線にする~

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4