見出し画像

【Unity】シーンにオブジェクトを自動で配置するエディタ拡張を作る

KuMA Advent Calendar 2023 7日目の記事です.

Unityでシーンに同じものをいくつか配置したいとき,オブジェクトをコピーして貼り付けて・・・と繰り返しても良いですが,木や石などたくさん配置したいときは面倒です.そこで,Unityエディタ拡張でオブジェクトを自動配置するスクリプトを作ってみました.

以下は,指定した半径の円周上に,指定した数のオブジェクトを配置するスクリプト CircleObjectPlacer.cs です.

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class CircleObjectPlacer : EditorWindow
{
    GameObject objectToPlace;
    float radius = 5f;
    int objectCount = 10;
    bool faceCenter = true;
    List<GameObject> placedObjects = new List<GameObject>();

    [MenuItem("Tools/Circle Object Placer")]
    public static void ShowWindow()
    {
        GetWindow<CircleObjectPlacer>("Circle Object Placer");
    }

    void OnGUI()
    {
        GUILayout.Label("Place Objects in a Circle", EditorStyles.boldLabel);

        objectToPlace = (GameObject)EditorGUILayout.ObjectField("Object to Place", objectToPlace, typeof(GameObject), true);
        radius = EditorGUILayout.FloatField("Radius", radius);
        objectCount = EditorGUILayout.IntField("Object Count", objectCount);
        faceCenter = EditorGUILayout.Toggle("Face Center", faceCenter);

        if (GUILayout.Button("Place Objects"))
        {
            Undo.RegisterCompleteObjectUndo(this, "Circle Object Placer Change");
            ClearObjects();
            PlaceObjects();
        }

        if (GUILayout.Button("Clear Placed Objects"))
        {
            Undo.RegisterCompleteObjectUndo(this, "Circle Object Placer Clear");
            ClearObjects();
        }
    }

    void PlaceObjects()
    {
        for (int i = 0; i < objectCount; i++)
        {
            float angle = i * Mathf.PI * 2 / objectCount;
            Vector3 position = new Vector3(Mathf.Cos(angle) * radius, 0, Mathf.Sin(angle) * radius);
            GameObject newObj = Instantiate(objectToPlace, position, Quaternion.identity);
            placedObjects.Add(newObj);

            if (faceCenter)
            {
                newObj.transform.LookAt(Vector3.zero);
            }
        }
    }

    void ClearObjects()
    {
        foreach (var obj in placedObjects)
        {
            if (obj != null)
            {
                DestroyImmediate(obj);
            }
        }
        placedObjects.Clear();
    }
}

UnityエディタのAssets/Editorフォルダにこのスクリプトを保存すると,Toolメニュー以下に新しい項目が現れます.

Circle Object Placerが生えた

配置するオブジェクト,円の半径,オブジェクト数,中心を向くかどうかを設定できるようにしてみました.

オブジェクト選択画面


オブジェクトを選択して「Place Objects」ボタンを押すと,無事シーンにオブジェクトを配置することができました.

シーンにオブジェクトを自動で配置できた!


clusterのサンプルシーンで作っていたので,そのままclusterにアップロードすることもできました.

clusterにもアップできた!


Unity上で繰り返しの作業を行うときは,エディタ拡張を作ると自動化できて便利です.
今回のスクリプトに追加すると良い機能としては,オブジェクトを配置する中心点の設定,空のGameObjectの子として配置するようにする,個々のオブジェクトの回転や大きさをランダムにする(これは木など自然のオブジェクトの配置に便利かもしれません)などがあると思います.

この記事で紹介したスクリプトは全部ChatGPTが書きました.会話履歴を公開しておくので,暇だったら"Continue this conversation"で会話を続けて機能の追加などやってみてください.

https://chat.openai.com/share/57cff1c9-5622-4a29-af0d-be109547230e

ここまで読んでいただきありがとうございました!

いただいたお金は書籍やお寿司の購入などに充てさせていただきます。