10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

グレンジAdvent Calendar 2024

Day 17

[Unity]3D?いいえ、一枚絵です。頂点変形でイラストを立体的に見せるネタ

Last updated at Posted at 2024-12-17

グレンジ Advent Calendar 2024 17日目担当の、flankidsです。
普段は操作、アニメーション、カメラワークなどで遊び心地を作ることを主にやっています。楽しいものを作るのが好きです!

今回は、一枚絵を立体的に見せるネタについて書いてみました。
もしこの記事がお役に立てたら「いいね」を押してもらえると、とても励みになります!

一枚絵を立体的に見せる

最近、デザイナーさんとの雑談でSpineを使ってイラストを立体的にアニメーションさせる作品が面白いよ〜と下記のページを共有してもらいました。

下記のSpineウェビナーを見たところ、立体表現用のボーンを割り当てて長方体を回すような要領で画像を頂点変形させることで、一枚絵をあたかも立体物かのように見せていることがわかりました。

考え方はシンプルなのでUnityだけでもこの表現なら再現できそうだと思い、挑戦してみました。

Unityでやってみた

Movie_023.gif

こんな感じでそれっぽく再現できました!
1枚の画像を切り分けたりせず、そのままで立体的に見せることができています。

元画像には下記のイラストを使用させて頂きました。

仕組み

イラストとCubeを並べて、正面から見た時に立体的な形状が一致するようにCubeの角度やスケールを調整します。

image.png

Cubeの頂点座標を平面に転写して、これらの座標からMeshを生成します。

image.png

※法線方向はZの正方向になっていますが、2D表示物は大抵Zの負の方向を向いているのでとりあえずシーン上でZスケールを-1にしています

CreateMesh.cs
using System.Collections.Generic;
using UnityEngine;
using TriangleNet.Geometry;

private void CreateMesh() {
    // cubeの頂点から、Mesh用の情報を作成
    _vertices = new Vector3[_cubeVertices.Length];
    _uvs = new Vector2[_cubeVertices.Length];
    for(var i = 0; i < _cubeVertices.Length; i++) {
        var vertex = (Vector2)_cubeVertices[i];
        _vertices[i] = vertex;
        // FIXME: 頂点は-1~1の範囲内に収める前提の処理
        _uvs[i] = vertex + new Vector2(0.5f, 0.5f);
    }

    if(_mesh == null) {
        _mesh = new Mesh();
        _meshFilter.mesh = _mesh;
    }

    // 生成したMeshに頂点・UVを登録
    _mesh.SetVertices(_vertices);
    _mesh.SetUVs(0, _uvs);

    
    // Triangle.NETを使って_verticesからtrianglesを作成
    // Triangle.NET: 不規則な点集合に対してDelaunay三角形分割を行うC#ライブラリ
    var polygon = new Polygon();
    foreach (var vertex in _vertices) {
        polygon.Add(new Vertex(vertex.x, vertex.y));
    }

    var triangulatedMesh = polygon.Triangulate();
    var triangles = new List<int>();
    foreach (var triangle in triangulatedMesh.Triangles) {
        for(var i = 0; i < 3; i++) {
            triangles.Add(triangle.GetVertexID(i));
        }
    }

    _mesh.SetTriangles(triangles, 0);
}

これで生成したMeshにスプライトが収まるように表示できるようになりました。

image.png

さらに、ここからCubeの回転に合わせてUVは維持してVertexを更新することで立体的にテクスチャが歪み、イラストが立体物のように見えるようになります。

book_roll.gif

UpdateVertices.cs
private void UpdateVertices() {
    // Cubeの上の座標を取得(zは0にする)
    GetVertices();

    // 頂点を更新。UVはそのまま
    for(var i = 0; i < _cubeVertices.Length; i++) {
        var vertex = (Vector2)_cubeVertices[i];
        _vertices[i] = vertex;
    }
    _mesh.SetVertices(_vertices);
}

所感

想像以上にそれっぽく動いて楽しいです。
仕組み上複雑な形状には対応できませんし、じっくり見ると歪みが目についてしまいますが、冒頭に記載したような参考元のアニメーションのようにプリミティブな形状をしたイラストの短い尺の演出には十分対応できそうです。
かなりリッチな見栄えになりそう。

そういう用途を考えると、UGUIとして表示するためにいろいろ手直しが必要ですね。
また、形状を決めてアニメーションを作るところまでをデザイナーさんが自由に作れるまでにはまだまだユーザーフレンドリーな形にはなっていないので、そのあたりもエディタ拡張を考えたいところ。

Spine含め、この手のツールやライブラリは今やたくさんありそうなので、いろいろ触って参考にしたいです。

参考資料

10
3
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
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?