uGUIで線を引く～その２：線の描画編～

# はじめに
前回、三角メッシュを描画しました
[uGUIで線を引く～その１：三角メッシュの描画](https://qiita.com/inpax23/items/1fc7202c08cfd0d3e8fc)
今回は、それを応用して、四角を作成します
# 作ってみる
前回は頂点３つでしたが、４つ用意して、メッシュを２つ描画するだけです

```csharp
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)
    {
        //（１）座標の準備
        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);
        // (２)（１）の座標に頂点を追加
        AddVert(vh, v1);
        AddVert(vh, v2);
        AddVert(vh, v3);
        AddVert(vh, v4);
        // (３)（２）で追加した頂点に三角形メッシュを２つ設定
        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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/5be9138c-1530-4728-3bd9-566824bf05e2.png)
(1)のv3,v4のy座標`100.0f`を、5.0fにすれば
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/10d2d01b-56be-19e4-1f35-489f423b7d24.png)
線になりました！
# 実用性をあげる
インスペクターで設定できるようにします。
ただ、線を引くのにいちいち4点を指定するのは面倒なので、2点と太さをもらって、描画するようにしてみます。

```csharp
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)
    {
        // （１）頂点を頂点リストに追加
        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));

        // （２）頂点リストを元にメッシュを貼る
        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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/28034a91-43e2-0b92-a1ed-0ea543c0bedf.png)
できました！
…が、ここで問題が。。
#線を動的に動かしたい
上記の例だと、プレイ前に設定した位置に線が引かれますが、**プレイ中にインスペクターでPosition1とPosition2を変更しても、線が変わりません。**
なぜかというと、確かに、変更したタイミングで再度OnPopulateMeshが呼ばれて、変更後の座標に頂点が増えますが、メッシュは、変更前の座標のインデックス(0,1,2,3)に描画しているため、**変更後の座標にメッシュが描画していない**ためです。
じゃあどうすればいいかというと、行頭でClearメソッドを呼んで、同インデックスの頂点の座標を更新するようにします

```csharp
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)
    {
        // （１）☆この行を追加！！過去にAddした頂点を全部削除!
        vh.Clear();
        // （２）あとは同じ。頂点を頂点リストに追加
        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));
        // （３）頂点リストを元にメッシュを貼る
        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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/e0a895ab-2d98-aef2-0f96-c1821b9c6dd1.gif)

ちなみに再生してなくても動かせます。便利！
![MoveOneLineInEditor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/f3448d39-7c47-924a-78fb-5616650b6608.gif)
# 次回予告
このままだと、太さが縦への長さにしているため、縦に線が引けません。
次は、線の角度によって、4頂点の位置を調整するようにします
[uGUIで線を引く～その３：線の端を垂線にする～](https://qiita.com/inpax23/items/d139d1b2d9dcaa3e3f97#_reference-7bbb69d7cc4a06a0671d)