実行中に編集したいTilemapが一つだけなら以下の方法でもできます。
- プレイモード中にタイルマップを編集する。
- プレイモード終了前に目的のTilemapコンポーネントをインスペクタから右クリックして「Copy Component」する。
- プレイモード終了後、コピーしたコンポーネントを元のTilemapオブジェクトに「Paste Component」すればプレイモード中に編集した内容を残せる。
ただ複数のTilemapを編集出来ないし、ちょっと面倒ではある。それにコライダーを一回OnOffしないと反映されてないっぽい気もする。
Editor拡張で何とかする。
プレイモード終了時にタイルマップのデータをキャッシュしてエディタに戻る時にキャッシュしたデータをセットする。
Editorフォルダを作ってその中に以下のスクリプトをコピーする。
Editorフォルダ以下でないとビルドしたときにエラーが出る。
[Window]から開けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEngine.Tilemaps; public class TilemapPersistent:EditorWindow { [SerializeField] private Tilemap[] target; List<TileBase[]> cachedAllTiles = new List<TileBase[]>(); List<BoundsInt> cachedBounds = new List<BoundsInt>(); [MenuItem("Window/TilemapExtend")] static void ShowWindow() { EditorWindow.GetWindow<TilemapPersistent>(); } private void OnGUI() { SetArrayProp(); EditorGUILayout.LabelField("プレイモード中に編集したタイルマップをそのままにします"); EditorGUILayout.LabelField("このウィンドウを開いていないと変更されません"); } private void SetArrayProp() { ScriptableObject target = this; SerializedObject so = new SerializedObject(target); SerializedProperty tilemaps = so.FindProperty("target"); EditorGUILayout.PropertyField(tilemaps, true); so.ApplyModifiedProperties(); } /// <summary> /// エディタの状態が変更されたときのコールバックをセットする /// </summary> private void OnEnable() { EditorApplication.playModeStateChanged += OnChangePlayMode; } private void OnDisable() { EditorApplication.playModeStateChanged -= OnChangePlayMode; } private void OnChangePlayMode(PlayModeStateChange playmode) { switch (playmode) { //プレイモードが終わって case PlayModeStateChange.EnteredEditMode: for (var i = 0; i < cachedBounds.Count; i++) { target[i].SetTilesBlock(cachedBounds[i],cachedAllTiles[i]); } break; //プレイモード終了時 case PlayModeStateChange.ExitingPlayMode: cachedAllTiles.Clear(); cachedBounds.Clear(); foreach (var tilemap in target) { //タイルデータの取得 BoundsInt bounds = tilemap.cellBounds;//タイルの範囲を取得 TileBase[] allTiles = tilemap.GetTilesBlock(bounds);//範囲内のタイルを取得 cachedBounds.Add(bounds); cachedAllTiles.Add(allTiles); } break; } } } |
タイルデータの取得方法を探すのに苦戦した。