こんにちは、とまです。
本日は、アイソメ風のグリッドの作り方を紹介していきます。
いろいろなゲームのなかには、
「普通の四角いグリッドではなく、斜め上から見下ろしたようなマップ」
を採用しているものがありますよね。
たとえば街づくりゲームでは、廃墟や工場、採掘施設などを斜めから見せることで、
3Dのように立体感のある街並み
を演出することができます。
しかし、いざアイソメ風のグリッドを作ろうとすると、
など、分からないことが増えてきます。
この記事では、Unityでアイソメ風のグリッドを作るときの基本的な考え方から、建物配置ゲームへの応用までを初心者向けに解説します。
- アイソメ風グリッドとは?
- なぜ街づくりゲームと相性がいいのか
- アイソメにすると座標管理も難しくなる?
- UnityのGridを利用する
- IsometricとIsometric Z as Yの違い
- Tilemapも利用できる
- グリッドの見た目と内部処理を分ける
- GridManagerの役割
- World座標とGrid座標
- 建物配置の基本的な流れ
- 建物のサイズを考える
- 配置できるかどうかを確認する
- PlacementManagerの役割
- 選択したマスをハイライトする
- グリッドは建築モードだけ表示してもいい
- アイソメでは建物の位置合わせが重要
- Sorting Orderにも注意する
- おすすめのスクリプト構成
- 今回のゲームでの最終的な流れ
- まとめ
アイソメ風グリッドとは?
まず、「アイソメ風グリッド」とは何でしょうか。
通常の2Dゲームでは、グリッドは四角形になっています。
将棋のマスのように□がならんでいるかんじですね。
一方、アイソメ風にすると、マスがひし形のように見えます。
これによって、地面を斜め上から見ているような印象になります。
重要なのは、アイソメ風とは「画面上で斜めに見せる」という考え方だということです。
ゲーム内部まで複雑な斜め座標にする必要はありません。
なぜ街づくりゲームと相性がいいのか
アイソメ風の表現は、街づくりゲームと非常に相性がいい方法です。
例えば、終末世界を舞台にしたゲームなら、
- 木材を集める施設
- 鉱石を採掘する施設
- 発電所
- 倉庫
- 工場
- 防壁
- 廃墟
- 道路
などを配置することになります。
これらを正面から描くよりも、斜め上から見たように配置すると、「街を上から眺めている」という感覚を出しやすくなります。
また、建物の前後関係も表現しやすくなります。
例えば、手前にある建物を大きく見せたり、奥にある建物を少し上側に配置したりすることで、2D画像だけでも奥行きを感じさせることができます。
アイソメにすると座標管理も難しくなる?
ここが初心者が一番悩みやすいところです。
結論から言うと、ゲーム内部では普通の2Dグリッドとして管理して大丈夫です。
例えば10×10のグリッドなら、
(0,0) (1,0) (2,0) ... (9,0)
(0,1) (1,1) (2,1) ... (9,1)
(0,2) (1,2) (2,2) ... (9,2)
...という形で管理します。
画面上ではこれが斜めになって、

のように見えるだけです。
例えば、

こんなゲーム画面があったとして、見た目は斜めですが、
建物の配置場所は、左上から右に3,下に3
の位置で登録されています。
つまり、
内部の座標は普通の2D
↓
Unityが画面上ではアイソメ風に表示する
という考え方です。
この方法を採用すると、建物の配置判定がかなり簡単になります。
UnityのGridを利用する
Unityには、グリッドを管理するためのGridコンポーネントがあります。
アイソメ風のゲームを作る場合、このGridを利用する方法がおすすめです。
UnityのGridには複数のレイアウトがあり、その中にIsometricがあります。
これを利用すると、Unity側でアイソメ用の座標変換を扱ってくれます。
そのため、自分で「X方向に進んだら画面上では右上に移動する」「Y方向に進んだら左上に移動する」といった計算を最初から全部作る必要はありません。
初心者の場合は、まずUnityのGridを利用して仕組みを作る方が分かりやすいでしょう。
IsometricとIsometric Z as Yの違い
Unityのアイソメ関連設定を見ていると、IsometricとIsometric Z as Yという項目があります。
最初は違いが分かりにくいと思います。
通常のIsometricは、基本的に地面を斜め上から見ているようなグリッドを作るためのものです。
一方、Isometric Z as Yは、Z方向の値を高さとして利用するような表現に向いています。
例えば、高さの違うタイルを積み重ねたり、立体的な地形を表現したりするときに便利です。
今回のような、
「地面に建物を配置する街づくりゲーム」
なら、まずはIsometricから始めれば十分です。
必要になった段階で高さ表現を追加していけば問題ありません。
Tilemapも利用できる
Unityには、Gridと組み合わせて使えるTilemapもあります。
Tilemapは、グリッド上にタイルを配置して地面や道路などを作るための仕組みです。
例えば、

という構成にして、Tilemapに地面の画像を配置できます。
作り方は、

Hierarchyで、
GameObject → 2D Object → Tilemap → Isometric
を選択します。
すると、基本的に
- Grid
- Tilemap
が作られます。
街づくりゲームでは、後から道路や地面の種類を増やしたくなることが多いので、Tilemapを利用する方法は非常に相性がいいです。
グリッドの見た目と内部処理を分ける
ここは今回のシステムで特に重要なポイントです。
グリッドには大きく分けて2つの役割があります。
1つ目は、プレイヤーに見せるためのグリッドです。
例えば、
- 建築できる場所を表示する
- 選択中のマスを光らせる
- 建築できない場所を赤くする
といった処理です。
2つ目は、ゲーム内部で使用するグリッドです。
こちらでは、
- どのマスが空いているか
- どのマスが建物に使われているか
- 建物が何マス使っているか
などを管理します。
この2つを分けておくと、後から見た目を変更してもゲームシステムへの影響を小さくできます。
GridManagerの役割
グリッドを管理するクラスとして、GridManagerを用意すると分かりやすくなります。
GridManagerの役割は、簡単に言えば、
「このゲームのグリッドについて管理するクラス」
です。
例えば、
- グリッドの幅
- グリッドの高さ
- グリッドの位置
- セルサイズ
- セルが使用済みかどうか
- World座標からGrid座標への変換
- Grid座標からWorld座標への変換
などを担当させます。
World座標とGrid座標
Unityで建物配置を作る場合、必ず覚えておきたいのが「World座標」と「Grid座標」です。
World座標は、Unityのゲーム世界の中での位置です。
例えば、
X = 3.2
Y = 1.8
のような値です。
一方、Grid座標は、
X = 3
Y = 2
のように「何マス目なのか」を表します。
プレイヤーが画面をタップした場合、
タップ位置
↓
World座標
↓
Grid座標
という変換を行います。
そして建物を配置するときは、
Grid座標
↓
建物を置くWorld座標
という逆の変換を行います。
この変換をGridManagerにまとめておくと、他のスクリプトから簡単に利用できます。
建物配置の基本的な流れ
街づくりゲームでは、次のような処理になります。
まずプレイヤーが建物を選択します。
例えば「木材生産施設」を選択したとします。
次にプレイヤーがグリッド上をタップします。
そのタップ位置をGrid座標に変換します。
例えば、
(4, 5)
というマスだったとします。
そこで、
「この位置に建物を置けるか?」
を確認します。
問題なければ建物Prefabを生成します。
最後に、建物が使用したマスを「占有済み」にします。
この流れを作っておけば、同じ場所に建物を重ねて配置してしまう問題を防げます。
建物のサイズを考える
街づくりゲームでは、すべての建物が1マスとは限りません。
例えば、
- 倉庫 → 1×1
- 木材生産施設 → 2×2
- 鉱石採掘施設 → 2×2
- 大型工場 → 3×2
といった違いがあります。
2×2の建物なら、配置したマスだけではなく、その周囲を含めた4マスを使用します。
そのため、建物Prefabや建物データに、
「この建物は何×何マスなのか」
という情報を持たせると便利です。
こうしておけば、後から大型建物を追加するときも、同じ配置システムを利用できます。
配置できるかどうかを確認する
例えば2×2の建物を配置するとします。
配置予定場所がすべて空いていれば配置可能です。
逆に、
■ □
□ □のように1マスでも別の建物が使用していれば、配置できないようにします。
つまり、建物を生成する前に、
必要なマスがすべて空いているか確認する
ことが重要です。
これをPlacementManagerなどの配置専用クラスに担当させると、GridManagerの役割が複雑になりすぎません。
PlacementManagerの役割
PlacementManagerは、その名前の通り「建物を配置する処理」を担当します。
例えば、
- 選択中の建物を管理する
- タップ位置を取得する
- 配置予定位置を取得する
- 配置可能か確認する
- 建物Prefabを生成する
- グリッドを占有する
といった処理を担当します。
イメージとしては、
GridManager = マスを管理する
PlacementManager = 建物を置く
という分担です。
このように役割を分けると、スクリプトが大きくなりすぎるのを防げます。
選択したマスをハイライトする
建物配置ゲームでは、選択中のマスを表示すると非常に分かりやすくなります。
例えばプレイヤーが建物を配置しようとしたとき、
のように配置予定場所を表示します。
この表示部分はGridVisualizerなどの別クラスに担当させると管理しやすくなります。
グリッドは建築モードだけ表示してもいい
常にグリッドを表示する必要はありません。
例えば通常画面では、
街だけを表示
しておきます。
建物ボタンを押して建築モードに入ったら、
グリッドを表示
します。
そして建物を配置したら、
グリッドを非表示
に戻します。
このようにすると、ゲーム画面をすっきりさせられます。
今回のような放置系ゲームでは、通常時は街を眺める時間も長くなるため、必要なときだけグリッドを表示する設計もおすすめです。
アイソメでは建物の位置合わせが重要
アイソメ風ゲームでは、グリッドが正しくても建物の画像がずれて見えることがあります。
これは、建物画像の「中心」と「地面に接する位置」が一致していないことが原因です。
建物の中心ではなく、地面に接する部分を基準に配置する必要があります。
見た目的に、手前の二辺をきれいに見せる必要があるということですね
特に大きな建物では、この調整が重要になります。
建物PrefabのPivotやSpriteの位置を調整し、グリッド上の基準点と建物の接地点を合わせると、自然に配置できるようになります。
Sorting Orderにも注意する
アイソメ風ゲームでは、建物同士の前後関係も重要です。
例えば、
奥の建物
↓
手前の建物
という関係を正しく表示しないと、建物が地面に埋まって見えたり、手前の建物が奥の建物より後ろに表示されたりします。
Unityでは、Sprite RendererのSorting OrderやSorting Layerなどを利用して表示順を調整できます。
規模が大きくなった場合は、Y座標を利用して自動的に表示順を変更する仕組みを導入する方法もあります。
ただし、最初から複雑な仕組みにする必要はありません。
まずは少数の建物を配置して、自然に見えるか確認しながら調整していきましょう。
おすすめのスクリプト構成
今回のようなゲームなら、最終的には次のような構成にすると分かりやすくなります。
GridManager
グリッドそのものを管理します。
PlacementManager
建物の配置処理を管理します。
GridVisualizer
グリッドや選択マスの見た目を管理します。
ProductionBuilding
配置された生産施設の生産処理を管理します。
このように役割を分けることで、
「グリッドの処理を変更したら建物の生産処理まで壊れてしまった」
という問題を避けやすくなります。
今回のゲームでの最終的な流れ
今回作っている終末世界の放置系街づくりゲームなら、最終的には次のような流れにできます。
建物ボタンを押す
↓
建築モードになる
↓
アイソメグリッドを表示
↓
プレイヤーがマスをタップ
↓
GridManagerがGrid座標を取得
↓
PlacementManagerが配置可能か確認
↓
建物Prefabを配置
↓
使用したマスを占有
↓
ProductionBuildingが生産開始
↓
食料・木材・金属などの資源が増える
この流れが完成すれば、街づくりゲームとしての基本的なループが作れます。
まとめ
Unityでアイソメ風グリッドを作るときは、最初から難しい座標計算を自分ですべて作る必要はありません。
まずはUnityのGridをIsometricに設定し、アイソメ表示をUnityに任せる方法がおすすめです。
そして、ゲーム内部では通常の2Dグリッドとして、
「どのマスが空いているか」
を管理します。
さらに、
GridManager→ グリッド管理PlacementManager→ 建物配置GridVisualizer→ グリッド表示ProductionBuilding→ 生産処理
というように役割を分けると、初心者でもシステムを整理しやすくなります。
アイソメ風グリッドは最初は難しく感じますが、考え方はそれほど複雑ではありません。
「内部では普通のグリッド、画面では斜めに見せる」
と考えることが、アイソメ風の街づくりゲームを作る第一歩です。
お疲れ様でした~。いかがでしょうか?
もし分からなければ気軽にコメントしてください!
今回はここまでです!
またお会いしましょう~


コメント