概要
以前の記事でTilemapの基本的な作成方法を紹介しました。
しかし、使用する画像がたくさんある場合はいちいちこの処理をするのは面倒です。
そこで、この記事ではこの処理を自動化する方法を紹介します。
以前の記事はこちらから
kiironomidori.hatenablog.com
使用するスクリプト
次のスクリプトを使用します。
using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEngine.Tilemaps; using System.IO; using System.Linq; [CustomEditor(typeof(CreateTilePalette))] public class CreateTilePaletteEditor : Editor { CreateTilePalette createTilePalette; public override void OnInspectorGUI() { //元のInspector部分を表示 base.OnInspectorGUI(); //読み込む? serializedObject.Update(); createTilePalette = target as CreateTilePalette; //ボタンを表示 if (GUILayout.Button("タイル作成")) { //スライス foreach (var img in createTilePalette.imgs) { createTilePalette.Slice(img); createTilePalette.CreatePalette(img); } //リフレッシュ EditorApplication.ExecuteMenuItem("Assets/Refresh"); } //変更を保存 serializedObject.ApplyModifiedProperties(); } } public class CreateTilePalette : MonoBehaviour { public List<Texture2D> imgs;//画像 [SerializeField] int spritePixelsPerUnit;//unity上での長さ1に対応するピクセル数 int row, column;//行数と列数 [SerializeField] string exportParentFolder;//ファイルの出力先 //画像を分割する public void Slice(Texture2D img) { //行数と列数を決定 row = img.height / spritePixelsPerUnit; column = img.width / spritePixelsPerUnit; //srcのパスとからインポート設定を取得 string imgPath = AssetDatabase.GetAssetPath(img); TextureImporter tI = AssetImporter.GetAtPath(imgPath) as TextureImporter; //テスクチャインポートプロパティを編集 tI.spritePixelsPerUnit = spritePixelsPerUnit;//何ピクセルで1マスか tI.spriteImportMode = SpriteImportMode.Multiple; tI.filterMode = FilterMode.Point; tI.textureCompression = TextureImporterCompression.Uncompressed; //ループで分割 var datas = new SpriteMetaData[row * column]; for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { int index = i * column + j; int x = j * spritePixelsPerUnit;//pixelSize.x; int y = img.height - (i + 1) * spritePixelsPerUnit; Rect rect = new Rect(new Vector2(x, y), Vector3.one * spritePixelsPerUnit); datas[index] = new SpriteMetaData() { name = $"{img.name}_{index}", rect = rect }; } } tI.spritesheet = datas; AssetDatabase.ImportAsset(imgPath, ImportAssetOptions.ForceUpdate); } //タイルパレットを作成 public void CreatePalette(Texture2D img) { //空のゲームオブジェクトを作成 GameObject prefabObjInstance = PrefabObjInstance(); //フォルダが存在しなければ作成 string exportFolder = $"{exportParentFolder}/{img.name}"; if (!Directory.Exists(exportFolder)) { Directory.CreateDirectory(exportFolder); } //タイルを追加 CreateTile(prefabObjInstance, img, exportFolder); //アセット化したら、シーンから削除 string exportObjPath = $"{exportFolder}/{img.name}.prefab"; PrefabUtility.SaveAsPrefabAsset(prefabObjInstance, exportObjPath); DestroyImmediate(prefabObjInstance); //アセットにGrid Paletteを追加 SetGridPalette(exportObjPath); } //プレハブのひな形を作成 GameObject PrefabObjInstance() { //空のオブジェクトを生成 GameObject obj = new GameObject("tmp_obj"); //Gridを追加 obj.AddComponent<Grid>(); //子供のゲームオブジェクトを作成 GameObject childObj = new GameObject("layer1"); childObj.transform.SetParent(obj.transform); //「Tilemap」と「Tilemap Renderer」をアタッチ childObj.AddComponent<Tilemap>(); childObj.AddComponent<TilemapRenderer>(); //返す return obj; } //タイルを作成して、マップに追加 void CreateTile(GameObject obj, Texture2D img, string exportFolder) { //Spriteを全取得 string imgPath = AssetDatabase.GetAssetPath(img); var sprites = AssetDatabase.LoadAllAssetsAtPath(imgPath).OfType<Sprite>().ToArray(); //rowとcolumnでループ for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { //タイルに使用する画像 Sprite targetSprite = sprites[i * column + j]; //タイルの作成 Tile tile = ScriptableObject.CreateInstance<Tile>(); tile.sprite = targetSprite; //アセットとして保存 AssetDatabase.CreateAsset(tile, $"{exportFolder}/{targetSprite.name}.asset"); //タイルマップに追加 Vector3Int pos = new Vector3Int(j, row - i - 1, 0); obj.transform.GetChild(0).GetComponent<Tilemap>().SetTile(pos, tile); } } } //プレハブにGrid Paletteを追加 void SetGridPalette(string exportObjPath) { //Grid Paletteを一時的に生成し、その文字列を読み込む string tmpGridPalettePath = "Assets/Palette Setting.asset"; var gridPalette = ScriptableObject.CreateInstance<GridPalette>(); AssetDatabase.CreateAsset(gridPalette, tmpGridPalettePath); //文字列を読み込む var text = File.ReadAllLines(AssetDatabase.GetAssetPath(gridPalette)).ToList(); //一時的なオブジェクトなので消す AssetDatabase.DeleteAsset(tmpGridPalettePath); //プレハブのassetファイルを読み込むGrid Paletteを無理やり追加するか判断 var objText = File.ReadAllLines(exportObjPath).ToList(); //既に追加されている場合は除外 if (objText[objText.Count - 1] != text[text.Count - 1]) { for (int i = 2; i < text.Count; i++) { objText.Add(text[i]); } //上書き File.WriteAllLines(exportObjPath, objText); } } }