本日は MRTK の技術調査枠です。
MRTK の GridObjectCollection を利用してスクリプトからスポーンオブジェクトの整列を行う方法を記事にします。
GridObjectCollection
MRTK の GridObjectCollection はオブジェクトを3次元的に整列する機能を提供します。
本スクリプトの Update Collection 関数はエディターまたはコードから利用可能です。
docs.microsoft.com
サンプルシーンとスクリプトの作成
サンプルシーンとスクリプトを作成します。
今回は MRTK の GridObjectCollection を利用するため、Unity プロジェクトに MRTK をインポートします。
MRTK のインポート手順は以下の記事などを参考にしてください
bluebirdofoz.hatenablog.com
GridObjectCollection を使って指定プレハブを指定の数スポーンして整列するサンプルスクリプトを作成しました。
・GridObjectCollectionSpawner.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; // GridObjectCollection参照のため using Microsoft.MixedReality.Toolkit.Utilities; [RequireComponent(typeof(GridObjectCollection))] public class GridObjectCollectionSpawner : MonoBehaviour { /// <summary> /// Spawnオブジェクト /// </summary> [SerializeField, Tooltip("Spawnオブジェクト")] private GameObject p_SpawnObject; /// <summary> /// GridObjectCollectionの参照 /// </summary> private GridObjectCollection p_GridObjectCollection; public void SpawnObjects(int a_Count) { if (p_SpawnObject == null) return; // GridObjectCollectionの参照を取得する p_GridObjectCollection = GetComponent<GridObjectCollection>(); // 子オブジェクトをいったん全て削除する for (int index = gameObject.transform.childCount - 1; index >= 0; --index) { // DestroyImmediate は呼び出した時点でオブジェクトを削除する // Destroy の場合、フレーム完了後に削除されるため、 // GridObjectCollection で正常に整列できない DestroyImmediate(gameObject.transform.GetChild(index).gameObject); } // 指定数のオブジェクトをスポーンする for (int index = 0; index < a_Count; index++) { // 子オブジェクトとしてスポーンする Instantiate(p_SpawnObject, gameObject.transform); } // GridObjectCollectionを使ってオブジェクトを整列させる p_GridObjectCollection.UpdateCollection(); } }
再生成を行う場合、GridObjectCollection への影響を避けるため、オブジェクトの削除には DestroyImmediate を利用しています。
Destroy はフレームの完了タイミングでオブジェクトの削除が行われますが、DestroyImmediate は即座に削除が行われます。
DestroyImmediate(gameObject.transform.GetChild(index).gameObject);
また、エディターからも利用可能なように拡張クラスも作成しました。
・GridObjectCollectionSpawnerEditor.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; // 拡張するクラスを指定する [CustomEditor(typeof(GridObjectCollectionSpawner))] public class GridObjectCollectionSpawnerEditor : Editor { private int makeCount; // GUIの表示関数をオーバーライドする public override void OnInspectorGUI() { // 元のインスペクター部分を表示 base.OnInspectorGUI(); // targetを変換して対象スクリプトの参照を取得する GridObjectCollectionSpawner targetScript = target as GridObjectCollectionSpawner; // public関数を実行するボタンの作成 if (GUILayout.Button("SpawnObjectsの実行")) { targetScript.SpawnObjects(makeCount); } makeCount = EditorGUILayout.IntField("Count", makeCount); } } #endif
スクリプトをシーンのオブジェクトに設定します。
今回はスポーンオブジェクトにボタンプレハブを参照しました。
また整列条件は GridObjectCollection に直接設定します。
動作確認
最初にランタイムでの動作を確認するため、シーンを再生します。
[Count]変数に生成数を指定して[SpawnObjectsの実行]ボタンをクリックします。
指定したオブジェクトが整列して生成されます。
シーンを再生せず、エディター上で実行しても利用できます。