UnityでMeshの頂点をムニャムニャする

# 起
某Unity1weekの題材の夏っぽいゲームを作ろうと思って、ノープランで波の表現とかを調べつつ実装したんですが、結局夏っぽいゲーム作成は断念しました。でももったいないのでここに記します。。。

# 波の計算方法とかはさておき
ともかくMeshの頂点を自由自在に動かしたい。

基本として、Meshを描画するのは`MeshRenderer`
Meshを保持しているのは`MeshFilter`
このMeshは自分で作ることができます。

[Unityで物理演算ゲームの作り方](http://qiita.com/divideby_zero/items/491d18cbc91d7fabd700)

でもちょっと書きましたが、Meshを生成するのってそんなに難しくないです。

MeshRendererとMeshFilterがあるGameObjectを作って
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/a8e7ed7a-d111-3e2a-a10a-987053d05aee.png)

`MyMesh`クラスをアタッチして、meshFilterをinspectorでセットしておきます。
`MyMesh`クラスは以下な感じ。

```csharp:MyMesh.cs

using System.Collections.Generic;
using UnityEngine;

public class MyMesh : MonoBehaviour
{
    [SerializeField]
    private MeshFilter meshFilter;

    private Mesh mesh;
    private List<Vector3> vertextList = new List<Vector3>();
    private List<Vector2> uvList = new List<Vector2>();
    private List<int> indexList = new List<int>();

	void Start ()
	{
	    mesh = CreatePlaneMesh();
	    meshFilter.mesh = mesh;
	}

    private Mesh CreatePlaneMesh()
    {
        var mesh = new Mesh();

        vertextList.Add(new Vector3(-1, -1, 0));//0番頂点
        vertextList.Add(new Vector3(1, -1, 0)); //1番頂点
        vertextList.Add(new Vector3(-1, 1, 0)); //2番頂点
        vertextList.Add(new Vector3(1, 1, 0));  //3番頂点

        uvList.Add(new Vector2(0, 0));
        uvList.Add(new Vector2(1, 0));
        uvList.Add(new Vector2(0, 1));
        uvList.Add(new Vector2(1, 1));

        indexList.AddRange(new []{0,2,1,1,2,3});//0-2-1の頂点で1三角形。 1-2-3の頂点で1三角形。

        mesh.SetVertices(vertextList);//meshに頂点群をセット
        mesh.SetUVs(0,uvList);//meshにテクスチャのuv座標をセット（今回は割愛)
        mesh.SetIndices(indexList.ToArray(),MeshTopology.Triangles, 0);//メッシュにどの頂点の順番で面を作るかセット
        return mesh;
    }
}

```

なんとこれだけで、ペラい板が表示されます！　やったー！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/21a2cfb4-1ea4-a854-a633-f2561ca8d347.png)

#じゃぁ、頂点をムニャムニャしよう
ということは、と、いうことはですよ

```csharp:頂点をムニャムニャ
    void Update()
    {
        for (var i = 0; i < vertextList.Count; i++)
        {
            vertextList[i] += new Vector3(Random.Range(-0.1f,0.1f), Random.Range(-0.1f, 0.1f),0);//全頂点のxとyをランダムでちょっと動かす
        }
        mesh.SetVertices(vertextList);
    }
```

これで、

![20170803_221953.gif](https://qiita-image-store.s3.amazonaws.com/0/37184/fd9cad2c-fe5f-689f-1fb6-d686650f03b1.gif)

はい！頂点がムニャムニャし始めた！

キモは、`SetUVs`や`SetIndices`は変更が無いのでセットしなくてもよいというところでしょうか。

# そして波へ・・・
では、波を作るには。
頂点が全然足りないので、横に100個ぐらい用意してあげます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/41cd477b-a412-ce3e-8c27-1ec3e9feb698.png)

そして、同じ要領で上端の頂点だけをムニャムニャ動かせば波の完成です。
※今回はSinカーブにしてみました。

```csharp:
    private int cnt = 0;
    public void Update()
    {
        for (var i = 0; i < vertexList.Count; i += 2)
        {
            var v = vertexList[i];
            v.y = Mathf.Sin((i + cnt) / 20.0f);
            vertexList[i] = v;
        }
        cnt++;
        mesh.SetVertices(vertexList);
    }
```
![20170803_223815.gif](https://qiita-image-store.s3.amazonaws.com/0/37184/4980075c-cd19-fd18-5c55-3c2a61504573.gif)

# 最後に

さらに、波に乗れるようにする。　などとなると、細かく`BoxCollider2D`を置いたりする必要があるようです。

そこらへんは
https://gamedevelopment.tutsplus.com/tutorials/creating-dynamic-2d-water-effects-in-unity--gamedev-14143
を参照してもらうとよいかも。（この例では、Meshをすごく大量に作ってますが。　必要・・・？なのかなぁ・・・？）

**素敵なムニャムニャライフを**