Unityで、Editor シーン上にプレハブとしてオブジェクトを配置する
プレハブとしてオブジェクトを作成するには、以下のようにコードを記述します。
要するに、InstantatePrefabを使用すると、インスタンス化ではなくプレハブとしてエディタに配置します。この方法ならば、プレハブとしての機能を活用出来るので、配置したオブジェクトの一括変更やパラメータの調整を楽に行うことが出来ます。ただしこれはEditor専用機能なので、実行時向けにInstantiateを記述しておくと吉です。#if UNITY_EDITOR
var tile = UnityEditor.PrefabUtility.InstantiatePrefab(prefab.gameObject) as GameObject;
#else
var tile = Instantiate(prefab.gameObject) as GameObject;
#endif
この方法を上手く使用すると、起動時に並べるようなオブジェクトをエディタ拡張で事前に並べ、シーンで完成後の図を確認しながら動作・UIの調整を行うことが出来ます。(その際、例えば二重配列のようなケースではオブジェクトの事前登録はできないので、生成後の各オブジェクトが自主的にオブジェクトを生成するコンポーネントに登録しに行くのが良さそうです)
シーン内にオブジェクトを並べる拡張は、例えばこんな感じです。ContextMenuをコンポーネントのメソッドに追加すると、 のマークから指定したメソッドを(実行していなくても)呼び出す事ができます。生成したオブジェクトと親子関係を持つのは生成一括追加・一括拡縮・一括移動・一括削除を楽にするためです。そうすれば、再生成したい際に一括削除→一括生成を楽に行えます。
なお、タイルベースなゲームの場合は自身のTransform.position以外にも座標値を持っておくと良さそうです。理由は簡単で、floatの値は誤差が出やすい為、transform.positionの値をベースに移動させると誤差る可能性があるからです。
画像はTiny Mobile Cartoon #1(無料のUIパック)より[ContextMenu("generate tiles")]
void GenerateTiles()
{
var tileGeneratePosition = transform;foreach( var tile in tileGeneratePosition.GetComponentsInChildren<Tile>())
{
DestroyImmediate (tile.gameObject );
}for(int x=0; x<sizeX; x++)
{
for( int y=0; y<sizeY; y++)
{
#if UNITY_EDITOR
Tile tile = UnityEditor.PrefabUtility.InstantiatePrefab(tilePrefab) as Tile;
#else
Tile tile = Instantiate(tilePrefab) as Tile;
#endif
tile.transform.parent = tileGeneratePosition;
tile.transform.localPosition = new Vector3(x, y, 0);
tile.tilePosition = new TilePosition(){ x = x, y = y };
}
}
}