うにてぃブログ

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

【Unity】Sprite を Mesh に変換する

Sprite は vertices, uv, triangles と Mesh の情報を持っている

これを利用して Sprite から Mesh を生成する

Sprite の Mesh を正しく取得するためには Mesh TypeTight にする必要がある

f:id:hacchi_man:20210118212057p:plain:w250

Sprite Mesh の確認

SpriteRenderer を に対象の Sprite をセットして Wireframe を表示させることで Mesh の確認ができる

f:id:hacchi_man:20210118212158p:plain:w300

Mesh の 生成

Project Window で Mesh を作成したい Sprite を選択し

Tools/SpriteToMesh で Mesh を作成できる

作成した Mesh がこちら

f:id:hacchi_man:20210118212327p:plain:w300

コード

using System.Linq;
using UnityEditor;
using UnityEngine;
 
public class SpriteToMesh
{
    [MenuItem("Tools/SpriteToMesh")]
    private static void Do()
    {
        var guids = Selection.assetGUIDs;
        foreach (var guid in guids)
        {
            var path = AssetDatabase.GUIDToAssetPath(guid);
            GenerateMesh(path);
        }
    }
 
    private static void GenerateMesh(string path)
    {
        var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
        if (sprite == null)
        {
            Debug.Log("Select Asset is not Sprite. " + path);
            return;
        }
 
        var mesh = new Mesh
        {
            vertices = sprite.vertices.Select(v => (Vector3) v).ToArray(),
            uv = sprite.uv,
            triangles = sprite.triangles.Select(t => (int) t).ToArray()
        };
 
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
        mesh.RecalculateTangents();
  
        var savePath = EditorUtility.SaveFilePanelInProject(
            "Select Save Path",
            sprite.name + "_mesh",
            "asset",
            "Select Save Path",
            System.IO.Path.GetDirectoryName(path)
            );
 
        if (string.IsNullOrEmpty(savePath))
            return;
        
        AssetDatabase.CreateAsset(mesh, savePath);
        AssetDatabase.Refresh();
    }
}