うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】ジグソーパズルの自動生成 ~5~

テクスチャを貼り付ける

ジグソーピースの生成ができたのでこれにテクスチャを貼り付ける
そのためには今の頂点座標から、uvを計算してやればよい

//uvのセット
var uv = new List<Vector2>();
foreach (var vertex in mesh.vertices)
    uv.Add(new Vector2(vertex.x / param.Horizontal, vertex.y / param.Vertical));
mesh.uv = uv.ToArray();

テクスチャを指定してみる

素材はこちらから利用させていただきました https://pixabay.com/ja/photos/%E6%9C%A8-%E8%87%AA%E7%84%B6-%E9%A2%A8%E6%99%AF-almtal-3226278/pixabay.com

テクスチャを指定するとこのようになります

f:id:hacchi_man:20200112235535p:plain

もとの写真サイズが、640 * 426 なのですが、正方形に表示されてしまっているため変に見えます
これを写真サイズのジグソーになるように対応します

コード修正

今までは分割数に応じて begin と end が大きくなっていっていたところを
分割数で割ることにより、 0.0 ~ 1.0 の範囲に収まるようにし

※ 2:2 分割であれば x:2 y:2 の座標を最大の頂点としていた

Mesh 生成時に uv はそのままの頂点座標をセットし
vertices はテクスチャのサイズを掛ける

       private static List<BezierPathSegment> GetPieceSegment(JigsawParam param, int x, int y, ref List<Border> borders)
        {
            // 略
            foreach...
            {
                var begin = new Vector2Int(x + position.x, y + position.y);
                var end = isClockwise
                    ? new Vector2Int(position.y == 0 ? x + 1 : x, y + position.x)
                    : new Vector2Int(x + position.y, position.x == 0 ? y + 1 : y);

                // 端のピース
                if...
                {
                                           // param.Size = new Vector2(horizontal, vertical)
                    ret.Add(new BezierPathSegment
                    {
                        P0 = begin / param.Size,
                        P1 = end / param.Size,
                        P2 = begin / param.Size,
                    });

                    continue;
                }

                var border = borders.Find(b => b.Begin == begin && b.End == end);
                if (border == null)
                {
                                           // param.Size = new Vector2(horizontal, vertical)
                    border = new Border(begin, end, GetBorder(begin / param.Size, end / param.Size));
                    borders.Add(border);
                }

                ret.AddRange(border.Segments);
            }

            return ret;
        }

        private static void GenerateMesh(JigsawParam param, List<Shape> shapes)
        {       
            // 略

            // uv をセット
            mesh.uv = mesh.vertices.Select(v => new Vector2(v.x, v.y)).ToArray(); 
            
            if (param.Texture != null)
            {
                // 頂点の位置をテクスチャに合わせる
                mesh.vertices = mesh.vertices
                    .Select(v => new Vector3(v.x * param.Texture.width, v.y * param.Texture.height, v.z))
                    .ToArray();
            }
        }

ジグソーのサイズを写真のサイズに変更

これによりテクスチャのサイズに合わせたジグソーを生成することができる

しかしながら、640 * 426 のテクスチャなので、サイズがすごいことになってしまうため最終的には調整が必要になる
f:id:hacchi_man:20200113195520p:plain