2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unityの操作に慣れていない人向けに】グリッドを塗るだけで3Dダンジョン爆速生成!レベルデザイン拡張「build Master」を自作した

2
Last updated at Posted at 2026-01-28

なぜ作ったのか

Unityでダンジョンや室内のレベルデザインをする際、こんな悩みはありませんか?

「もっとRPGツクールのような感覚で、ポチポチとマップを作りたい!」

既存のアセットでも似たようなものはありますが、「自分のプロジェクトに特化した、軽量で融通の利くツール」が欲しくなり、Unityのエディタ拡張(EditorWindow)で自作しました。(unityの操作に慣れていない人向けに作っています)

本記事では、作成したツール「build Master」の機能紹介と、それを実現するためのエディタ拡張の実装を共有します。

成果物 build Master

エディタウィンドウ上のグリッドをマウスでドラッグするだけで、シーン上に床や壁が生成されます。

こだわった機能
グリッドペイント: 左クリックで配置、ドラッグで連続塗りつぶし。

3レイヤー管理: 「床」「壁」「ドア」を個別に管理し、重なりを考慮。

4x4 詳細編集: 1つのグリッドをさらに16分割して編集可能(穴の開いた壁とか)。

オートスケーリング: ただのCubeをPrefabにするだけで、自動で引き伸ばして配置。

実装ポイント

ここからは、実際にどうやって実装したのか、C#のコードを交えて解説します。

1. データ構造:1マスを「16分割」で管理する

単に「壁がある/ない」の bool 管理だと、細かい表現ができません。かといって最初から細かいグリッドにすると作業効率が落ちます。 そこで、1つのセグメント(マス)に対して、4x4=16個のサブ情報を保持するクラスを設計しました。

buildMaster.cs
[System.Serializable]
public class SegmentData
{
    // 4x4 = 16個のサブグリッドのPrefabインデックスを保持
    // -1なら空、0以上ならPrefabID
    public int[] segmentPrefabIndices = new int[16];
    
    // 詳細モード(4x4)を使用しているかどうかのフラグ
    public bool isDetailed = false;
    
    // ドアの情報
    public int doorPrefabIndex = -1;
    public RectInt doorRect;

    // ...(初期化や塗りつぶしメソッドなど)
}

これにより、普段は1マス一括塗りつぶし と こだわりの4x4編集 を同じデータ構造で無理なく管理しています。

2. EditorWindowでのお絵かき実装

EditorWindow の OnGUI メソッド内で、Event.current を監視してマウス入力を処理します。 特に「ドラッグして連続配置」する挙動は、以下のような処理で実現しています。

buildMaster.cs
private void HandleGeneralInput(Event e, Rect gridArea)
{
    if (gridArea.Contains(e.mousePosition))
    {
        // マウス座標からグリッドのインデックス(x, y)を計算
        Vector2Int cellPos = GetCellFromPosition(e.mousePosition, gridArea);
        
        // 左クリック (MouseDown)
        if (e.type == EventType.MouseDown && e.button == 0)
        {
            if (e.alt) {
                // Altキー押下ならスポイト(コピー)処理
            } else {
                // 塗り始めの処理(ドラッグモードの開始)
                // 例: 今のモードが「壁塗り」なら DragMode.WallPainting に遷移
            }
            e.Use(); // 重要!イベントを消費して、裏側のシーンビュー等を操作しないようにする
        }
        // ドラッグ (MouseDrag)
        else if (e.type == EventType.MouseDrag && e.button == 0)
        {
            // ここで連続配置処理!
            // DragModeに応じてペイントや消しゴム処理を実行
            PaintCell(cellPos);
            e.Use();
        }
    }
}

Event.Use() を呼ぶことで、エディタウィンドウをクリックした瞬間にフォーカスが外れたり、意図しないイベントが走るのを防いでいます。

3. オートスケーリング(Prefabの自動変形)

このツールの最大の利点は専用のモデリングが不要な点です。 Unity標準のCubeで作った適当なPrefab(1m x 1m x 1m)でも、ツール側で計算してピタッと配置します。

具体的には、生成時にPrefabの持っている大きさを取得し、目標サイズとの比率を transform.localScale に適用しています。

buildMaster.cs
// PrefabのBoundsを取得するヘルパー関数
private Bounds GetPrefabBounds(GameObject prefab)
{
    // 一時的にインスタンス化して計算(計算後即破棄)
    GameObject tempInstance = Instantiate(prefab);
    // ... Rendererのboundsを計算 ...
    DestroyImmediate(tempInstance);
    return calculatedBounds;
}

// 生成時の処理(抜粋)
private void GenerateFloor(Transform parentRoom)
{
    // ...
    // 目標サイズ(グリッド設定から算出。例: 5.0f)
    float targetWidth = tileSize_real; 
    float targetDepth = tileSize_real;
    
    // 元のPrefabのサイズを取得
    Bounds prefabBounds = GetPrefabBounds(prefab);
    Vector3 baseSize = prefabBounds.size;

    // 比率を計算
    float scaleX = targetWidth / baseSize.x;
    float scaleZ = targetDepth / baseSize.z;
    
    // スケール適用
    mergedObject.transform.localScale = new Vector3(
        originalScale.x * scaleX, 
        originalScale.y, // 高さは維持
        originalScale.z * scaleZ
    );
}

まとめ

Unityのエディタ拡張は、最初は敷居が高く感じるかもしれませんが、ポイントを押さえれば自分好みのツールを作ることができます。自分はこのツールをVRのワールド構築に使用しています。

特に、今回のような「グリッドベース」のアプローチは、2D配列の管理だけで済むため、初心者の方のエディタ拡張入門としてもおすすめです。

unityを初めて触るような人でも取り扱えるようなツールになっているので使って下さると喜びます。
boothとgithubにあげています。

booth:https://inoue1213.booth.pm/items/7902268
github:https://github.com/mami1213/buildMaster

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?