Search Unity

つい最近 2018.2 リリースで加えた Hexagonal Tilemap サポートに続いて、Unity 2018.3 のリリースで、Isometric Tilemap サポートを導入しました。新しいタイルマップ機能は、等角グリッドと六角形グリッドのレイアウトに基づいて 2D 環境を作成できる素早く高性能な方法を提供します。このようなグリッドレイアウトは『Diablo』や『Fallout』フランチャイズの初期、『Civilization』、『Age of Empires』、その他多くの懐かしいゲームクラシックで良く見られます。

どちらのレイアウト機能も以前 Unity 2017.2 で導入された既存のタイルマップシステム上に構築されているので、使用も同様に簡単です。新しい機能も、エディターにもとから搭載されていますが、Unity の今後のリリースでは、パッケージマネージャーに移されるかもしれません。

紹介した技術を試してみたい方のために、アニメーション化したキャラクターと複数環境のタイルセットを含む事前設定済みの Isometric Starter Kit プロジェクトを作成しました。こちらから 無料でダウンロードできます

Isometric Tilemap の Project Settings

タイルマップを使い始める前に、プロジェクトを正しく設定することが重要です。Isometric Tilemap は 2D スプライトで機能していて、上から見下ろすアイソメトリックビューを正しく機能させるために、正しいレンダラーソートに依存しています。そのため、奥のタイルが最初にペイントされ、手前のものがその上にペイントされなくてはなりません。

画面上に 2D オブジェクトがペイントされる順番をカスタマイズするには、Unity の Custom Axis Sort 機能を利用できます。この設定は、カメラごと(現在、これは LWRP や HDRP を含むスクリプタブルレンダーパイプラインで Custom Axis Sort 機能を使う場合のデフォルトです)、またはプロジェクトレベルでグローバルに定義できます。

プロジェクトレベルで Custom Axis Sort を定義するには、Edit > Project Settings > Graphics の順に移動します。Camera Settings セクションに、Transparency Sort Mode ドロップダウンと、Transparency Sort Axis の X、Y、Z の値を設定するフィールドが表示されます。

デフォルトでは、Unity の Transparency Sort Axis は X、Y、Z がそれぞれ 0、0、1 に設定されています。ただし、すべての 2D タイルは実際には同じ Z 平面上にあります。そのため、画面の深度ではなく高さを使用して、どのタイルが後方、または、前方にあるのかを判断します。画面上で高い位置に配置されているタイルは、低い位置に配置されているタイルの後方にソートされます。位置の高さに基づいてタイルを並べ替えるには、 Transparency Sort Mode を Custom に変更します。そして、 Transparency Sort Axis の値を (0, 1, 0) に設定します。

2D ソートについて詳しくは、Unity ドキュメントの 関連ページ を参照してください。

場合によっては、Transparency Sort Axis の Z 値も調整する必要があります。これについては、このブログ記事で詳しく説明します。

タイルマップのタイプ

タイルマップの機能は、連携して動作するいくつかのコンポーネントで成り立っています。最初の 2 つは Grid ゲームオブジェクトと Tilemap ゲームオブジェクトです。Grid を作成するには、Hierarchy ウィンドウ内の任意の場所を右クリックし 2D Object を選択し、使用する Tilemap の種類を選択します。デフォルトでは、それぞれの新しい Grid は、対応するタイプの子の Tilemap ゲームオブジェクト 1 つと一緒に作成されます。現在利用可能な Tilemap ゲームオブジェクトのタイプは以下の通りです。

Tilemap – 矩形の Grid と Tilemap を作成します。この Tilemap の使用例は、Unity の 2D Game Kit をご覧ください。

Hexagonal Point Top Tilemap – 六角形の Grid と Tilemap を作成します。このとき、六角形の頂点の 1 つが上を向いています。

Hexagonal Flat Top Tilemap – もう 1 つの六角形の Grid タイプです。このとき、六角形の上に来る辺は画面の上辺に平行です。

最後の 2 つのタイプ、IsometricIsometric Z as Y は 2 つの異なる等角グリッドを実装します。この 2 つの違いは、等角で作成したレベルに少し高くなったプラットフォームを置く場合など、さまざまなタイルの高さをシミュレートするときに発生します。

通常のIsometric Tilemap は、タイルの高さごとに別々の Tilemap ゲームオブジェクトを作成する場合に最適です。これにより、衝突形状の自動作成のプロセスが簡単になります。ただし、1 つのレイヤー上のすべてのタイルは同じ「平面」上になければならないため、タイル間の高さのばらつきに関しては、あまり柔軟ではありません。

Isometric Z as Y Tilemap の場合、各タイルの Z 位置の値はカスタムの Transparency Axis Sort 設定と組み合わせて使用​​され、タイルが重なって表示されます。Z as Y Tilemap 上の描画は、ブラシの Z 設定を動的に調整して高さを変えます。Z as Y Tilemap を正しくレンダリングするには、Custom Transparency Sort Axis にも Z 値が必要です。

ノート:ここに表示されているアセットは、Isometric Starter Kit プロジェクトの Temple タイルセットのものです。完全に無料ですので、気軽にお試しください。そして、独自の環境を創造して楽しんでください。

Grid を Tilemap ゲームオブジェクトを固定する「イーゼル」と考えてください。Tilemap は本質的には、タイルを描くキャンバスです。Tilemap 上でペイントするには、ブラシとパレットも必要です。Tile Palette は、タイルアセットを保持するものです。その後、ブラシツールでそれらを選択してペイントを開始します。

Tile Palette を作成するには、Window > 2D > Tile Palette の順に選択します。新しく開いたウィンドウの左上のドロップダウンから Create New Palette を選択します。使用目的に適する Grid タイプを設定してください。この例では、通常の Isometric Tilemap と Isometric Starter Kit プロジェクト のアセットを使用します。Isometric タイルの寸法をカスタマイズできるようにするには、Palette の Cell Size を Manual(手動)に設定します。この場合、タイルの寸法は、X が 1、Y が 0.5 のグリッドに対応しています。ただし、それぞれのユースケースによって、解像度、インポート時に選択されたユニット値あたりのピクセル数、アセットの寸法によって異なります。基本的には、タイルを回転するときの等角角度によって異なります。

アセットをインポートするときの注意

アセットに適切な正しいインポート設定とタイルマップサイズについては、あまりご存知ないかもしれません。アセットの最初の寸法に基づいた一般的な規則があります。まず、タイルの解像度を見てください。通常、ブロックを表す等角タイルは、その幅より高さがあります。「平らな」タイル(立方体ではなく平面のように見えるタイル)は、縦の長さよりも幅が広くなります。ただし、それらの幅はすべて同じです。そのため、タイルにちょうど Unity の 1 ユニットを使用する場合は、タイルのインポート設定の Pixels Per Unit の値を幅(単位はピクセル)と同じに設定します。時には、この値の調整が必要な場合もあるかもしれません。通常は、値を減らす(またはアセットの実際の解像度を上げる)ことによって調整します。これは、いくつかのタイルが複数のグリッドセルを使い、隣接するタイルの上に重なるように見える効果を作成する場合に役立ちます。

タイルの正しい Y グリッド値を決定するために、1 つのタイルの底面(または上面)の高さを幅で除算します。これによって、X が 1 の場合の X に相対する Y 値が得られます。いくつかの例を見てみましょう。

このプロジェクトで使用しているピクセルアートでは、すべてのタイルの基本の高さは 32 ピクセル、幅は 64 ピクセルです。 したがって、使用するグリッドのサイズは Y が正確に 0.5 です。

サンプル画像の 2 番目のブロックは、Golden Skull Studios のアセットパックからのものです。こちら で取得できます。サンプルタイルは参照しやすいように縮小されていますが、元のアセットの幅は 128 ピクセルです。 タイルの底面の高さは約 66 ピクセルで、Y グリッドサイズは 66/128、つまり約 0.515 ユニットです。

基本的なタイルマップワークフロー

正しいグリッド寸法を決定したら、パレットにタイルをいくつか加えましょう。タイルスプライトの 1 つを、Tile Palette ウィンドウにドラッグするだけです。これでタイルアセットが作成されます。タイルアセットには、使用するスプライト、色、生成するコライダーのタイプのようなそれ自体についての情報が含まれています。パレット上のタイルに関する詳細情報を表示したい場合は、Tile Palette ウィンドウ上部の選択ツール(S)を選択して、タイルをクリックします。これで、インスペクター内で、どのタイルアセットが参照されているのかを確認できます。

新しいタイルをタイルマップにペイントするには、ブラシツール(B)を選択して、パレットのタイルをクリックします。これで、シーンビューで選択したタイルでペイントできるようになります。他のペイントツールには、消しゴム(D)、ボックスの塗りつぶし(U)、塗りつぶし(G)、タイルピッカー(I)があります。

時には、パレット自体のタイルの配置を編集したいこともあるでしょう。ツールバーのすぐ下には、Edit ボタンがあります。クリックすると、パレット編集モードになります。この間、ツールはタイルパレット自体の操作をします。必要な変更を加えたら、忘れずにこのモードを終了してください。

Tilemap Renderer のモード

以下の例のように、同じタイルマップにあるにもかかわらず、異なるタイプのタイルが正しくソートされない場合があります。

これは、Tilemap Renderer コンポーネントの Mode 設定によって決まります。デフォルトでは、Mode は Chunk に設定されています。

Chunk モードはタイルマップのパフォーマンスコストを削減するのに効果的です。各タイルを個別にレンダリングするのではなく、タイルをまとめて大きなブロックとして一括レンダリングします。ただし、その使用には主に 2 つの欠点があります。1 つ目は、シーン内の他の 2D オブジェクトとの動的ソートをサポートしないことです。つまり、タイルマップが Chunk モードの場合、キャラクターなど他のオブジェクトの前面や背後に動的に並べ替えることはできません。Order in Layer に基づいて 1 度に前面か背後、どちらかだけが可能です。ただし、ゲームを最適化したい場合は依然として非常に効果的であり、広い範囲の地面をバッチレンダリングするのに有用です。

しかしながら、これでは、さまざまなタイルどうしを互いにソートできない問題を回避できません。2 つ以上の異なるスプライト(すなわちテクスチャ)から来るタイルをバッチレンダリングするためには、スプライトを 1 つのスプライトアトラスアセットに統合する必要があります。

スプライトアトラスを作成するには、Assets > Create > Sprite Atlas の順に選択します。インスペクターのスプライトアトラスの設定には、Objects for Packing のリストがあります。バッチレンダリングするタイルをすべてこのリストにドラッグして、正しいインポート設定を行うだけです。通常は、個々のスプライトの設定と同じです。

それが済むと、タイルは正しくソートされます。しかし、これらは再生モードかランタイムにのみ設定した通りに表示されます。

そのため、編集中は Tilemap Renderer の Mode を Individual に設定にしておくほうが良いでしょう。このモードにすると、各タイルを別々にソートします。つまり、再生モードでなくても正しいレンダリングで表示されます。これは、まだレベルを変更中の場合には非常に便利です。レベル構造が整ったら、いつでも Tilemap Renderer の Mode を Chunk に戻すことができます。

Tilemap Renderer の Mode が Individual の場合は、キャラクターと動的にソートしたい、または、それぞれ相互に動的にソートしたい木、小道具、盛り上がった地面などのオブジェクトを追加する場合にも便利です。このブログ記事では、すべてのタイルマップには Individual モードを使用します。

複数のタイルマップの使用

同じグリッド上で複数のタイルマップを使いたい場合もあるかもしれません。Isometric Tilemap と Hexagonal Tilemap の場合は、レベルに小道具などのオブジェクトを加えグリッドと整列させたいときや、最初のレイヤーより高く見えるタイルを追加したいときに便利です。

もう 1 つのマップをグリッドにアタッチするには、Grid ゲームオブジェクトを右クリックして、対応するタイプの新しいタイルマップを作成します。

新しいタイルマップのペイントに切り替えるには、 Tile Palette ウィンドウに戻り、メインツールバーのすぐ下にある Active Tilemap を変更します。

高い領域の追加

レベルに周りより高い地面を加えるには、一般的に 2 つの方法があります。どちらを使用するかは大抵、選択したタイルマップのタイプによって異なります。それぞれのケースを見てみましょう。

また、そのトピックに関する短い動画を作成しました。動画では、方法の 1 つ、通常の Isometric Tilemap を使う方法や、衝突領域をタイルに加えることも紹介しています。これら興味のある方は、下の動画をご覧ください。

通常の Isometric Tilemap を使用

通常の Isometric Tilemap の場合は、単に、同じ Grid 下に Tilemap を作成し、Order in Layer の値を高く設定します。次に、Tile Anchor を変更して、新しいレイヤーをグリッド上のより高い位置に固定します。

地面の高さのタイルマップは、Tile Anchor の X と Y がそれぞれ 0 でした。新しいレイヤーを 1 ユニット高くペイントしたいので、新しい Tilemap のアンカーポイントを (1, 1) に変更します。さらに、その Order in Layer を 1 にして、地面の高さよりほんの 1 ユニット高くします。

これで、Active Tilemap を 2 番目に作った違う高さのものに変更してペイントできます。

Z as Y Isometric Tilemap を使用

1 つのタイルマップを使って異なる高さをシミュレートすると便利な場合があります。このようなときは、 Isometric Z as Y Tilemap と Grid を使用します。

Isometric Z as Y Tilemap を使用する場合、各タイルの Z 値はタイルのレンダリング順序に影響を与えます。Tile Palette の下部にあるブラシの Z Position の設定を使用して、ペイント中でもタイルの Z 値を調整できます(これは、+ と – のホットキーを使用しても変更できます)。

ただし、Z 値が正しく反映され、タイルが正しくソートされるようにするには、Custom Axis Sort 値に戻って Z の値が効力を持つようにする必要があります。ここで使用する数値は、Unity が等角グリッド上のセル位置をワールド空間値に変換する方法に直接関係しています。

例えば、X、Y、Z がそれぞれ 1、0.5、1(等角投影のデフォルト)の Grid では、Z 軸のソート値は -0.26 になります。この数値の計算方法に興味がある方、またはセルサイズが異なるグリッドを使用する方は、さらに読み進むと状況に適した Z 値を見つける方法が説明されています。

正しい Custom Axis Sort 値を設定したら、Z 値が異なるタイルのペイントを開始できます。デフォルトでは 1 に設定されている Grid の Z 値を変化させて、Z 値によるタイルの上下動の増分を調整することもできます。

Z 値を計算

軸ソートの Z 値を計算するために使用できる一般式があります。 まず、Grid の Y を取得します。Y がまだ決まっていない場合は、このブログ記事のはじめにあるアセットのインポートに関するノートを参照してください。この値に -0.5 をかけて、0.01 を減じます。

この公式に従うと、寸法が (1, 0.5, 1) のグリッドの Z ソート値は -0.26 になります。この軸ソート値で、(1, 0.5, 1) のグリッドのタイルはすべて正しくソートされます。

この値と計算について詳しく知りたい場合は、ドキュメント を参照してください。ドキュメントでは 2D レンダラーがどのように挙動するか、そして等角のセルをワールド空間値に変換するときにどんな方法が使われるか、詳細に説明しています。

衝突を加える

一部のタイルよりも高く置いたタイルがあるので、衝突を利用してプレイヤーが移動できる領域やその間の遷移を制御できます。

衝突を加える方法はたくさんあります。しかし、ここでは、斜道を使用してレベルに沿ってプレイヤーを昇降させる必要があるため、どのオブジェクトにコライダーを設定すべきか否かは明確ではありません。代わりに、追加のタイルマップを使用して手動で衝突を定義できます。

このプロジェクトでは、衝突領域を定義するために使用するさまざまな形状に合ったスプライトをいくつか作成しました。プレイヤーを通らせたくない領域で、これらの形状を 3 番目のタイルマップ上にペイントします。例えば、私たちはプレイヤーが崖をまっすぐよじ登るのではなく、斜道だけを通って崖に登るようにしたいと思っています。

タイルを他のレベルとは異なる色にするために、Tilemap Renderer コンポーネントにカスタムのマテリアルを追加することもできます。

衝突タイルを配置したら、Tilemap Collider コンポーネントを衝突のタイルマップに追加します。これで、スプライトの形状に基づいて個々のタイルごとにコライダーが自動生成されます。

パフォーマンスを向上させるために、Composite Collider 2D コンポーネントを加えて、その Used by Composite に必ずチェックを入れます。このようにして、個々のコライダーの全てを 1 つの大きな形に統合します。

小道具を加える

レベルに小道具を追加するのはとても簡単です。小道具のスプライトをシーン内の任意の場所に手動で配置するか、小道具を個別のタイルにして Tilemap Grid にアタッチします。自分のケースに最も適している方法を選択できます。

このプロジェクトでは、手動でレベルの周りにいくつかの木を配置しました。木とキャラクターはレイヤー内で同じ Order in Layer を持っているので、それらは動的に前後に並べ替えることができます。

コライダーを使用して、プレイヤーが木を通過できるポイントを定義できます。これを行うにはいくつかの方法があります。

最初の方法は、動画で示されているように、オブジェクトに子コライダーをアタッチし、必要に応じてその形状を変更する方法です。

もう 1 つの方法は、スプライトエディター内でオブジェクトの Custom Physics Shape を定義する方法です。

スプライトエディターを開くには、オブジェクトのスプライトを選択し、インスペクターで Sprite Editor ボタンをクリックします。左上のドロップダウンで、Custom Physics Shape エディターに切り替えます。ここで、カスタムコライダーの境界を定義する多角形を作成することができます。

物理形状を定義したら、Polygon Collider コンポーネントをオブジェクトにアタッチします。すると、その形状に対応します。

タイルマップでタイルの小道具を使用する場合は、 Grid コライダーも使用できます。小道具タイルに合うタイルアセットを選択します(やり方がわからない場合は、「基本的なタイルマップワークフロー」セクションを参照してください)。Collider Type のドロップダウンが表示されます。デフォルトでは、これは Sprite に設定されています。つまり、自動生成されたコライダーは、以前に説明した物理形状を使用します。それをグリッドに設定すると、小道具がアタッチされているグリッドセルの形状と常に正確に一致します。これは、コライダーを実装するための最も正確な方法ではないかもしれませんが、特定のタイプのゲームには有用です。

これらのタイルに Grid コライダーを使用するには、小道具のあるタイルマップを選択し、Tilemap Collider コンポーネントを加えます。

Rule Tile の使用

Rule Tile は、タイルペイントのワークフローを自動化するのに非常に役立ちます。Rule Tile はタイリングのためのパラメーターが追加された通常のタイルのように挙動します。これらのパラメーター(またはルール)を使用して、タイルは隣接するタイルに基づいてどのスプライトをペイントするかを自動的に選択します。

Rule Tile は、様々にローテーションするタイルを手動で選択したくない場合(崖やプラットフォームを作成する場合など)に便利です。同じタイルのさまざまなバリエーションをランダムにして、明らかにパターン化してしまうのを避けたり、アニメーション化したタイルを作成したりする場合にも利用できます。

Isometric と Hexagonal の Rule Tile は、GitHub の Unity の 2D Extras リポジトリから入手できます。それらには、もっと試してみたくなるような便利なタイルマップ機能のアセットも多く含まれています。

Isometric Starter Kit プロジェクトの様々なタイルセットのそれぞれにあらかじめ設定された Rule Tile も加えました。ここにあるのは、それらのプロジェクトに含まれるいくつかのタイルの例です。

さらに研究するために

Unity の Isometric Tilemap について様々なことを説明したので、ぜひ、Isometric Starter キットのプロジェクトをダウンロードしてお試しください。プログラマーの方は、スクリプトを通してタイルマップを操作することも可能ですので、それも興味があればお試しください。

例えば、下のビデオは、Isometric Tilemap と連携する簡単なキャラクターコントローラーを実装する方法を紹介しています。

このプロジェクトのアートワークは @castpixel によって Unity のために作成されたものです。その作品例は こちら をご覧ください。Unity を使った 2D ゲームの作成方法をもっと学びたい方は、Unity を学ぶのサイトでいくつかの素晴らしいコースがあります。タイルマップを使って実験するための 2D アセットがさらに必要な場合は、Unity Asset Store もご覧ください。

15 コメント

コメントの配信登録

コメント受付を終了しました。

  1. The link of Isometric Starter kit project is broken, “File not found” :(

  2. link to download demo project not working, i got this message: “File not found

    The specified document has not been found on the server.”, anyone have same problem? need help.

  3. Sadly, the download is broken.

    1. i got same problem :(

  4. Looks nice, but the Tilemap system is slow to render large maps. If I use chunk mode instead of individual mode, performance improves, but z ordering does not work properly. (Even when packed with SpriteAtlas) This article’s demo is also the same problem, is there any workaround?

  5. This tutorial needs to mention the importance of anchor points of tilemaps, as well as anchor point of the tile palette! The Unity default is 0.5, 0.5 but this is not what is used in this iso tutorial. If mistakenly relying on the Unity defaults, you end up with the “tall” tiles being vertically centered in the tile space rather than sitting on their “bottoms” so to speak.

    1. That’s a good point, I think it should be set as 0.5, 0.5 and “For Sprites of an Isometric Tilemap, it is recommended to set the Pivot of the Sprite where the ‘ground’ should be relative to the Sprite.”. So for example all flat tiles: Pivot as Custom: 0.5, 0.25 – all tiles will be in the right place, both in the Tile Palette and on the Scene.
      Only then we will get: a good depth sorting – @david with these changes you can walk behind tiles that are a level above you, colliders in the right place – if we decide to use Collider Type: Grid, and the most importat – GetCellCenterWorld, WorldToCell, CellToWorld etc., because in this example we can’t instantiating a GameObject in the right place, the center of the cell. Grid based movement is impossible without that, and also other useful things.

      I hope someone reads what we write here.

  6. Thanks so much for this blog post guys, exactly the information I was looking for!
    I second the forum thread

  7. Well, this is very nice, but it does not work correctly in a lot of cases, you cant walk behind tiles that are a level above you, even in your examples it does not work.
    If you could publish the z as y example that would be nice.

    1. Yes, you can. We built this isometric feature with that in mind. Please see https://youtu.be/2DsKCJsEzSA?t=261 for an example.

      1. Your video links to an example of character depth sorting against a DECORATION, no? The commenter (david) is talking about going behind level tiles, which in this iso example doesn’t work. In fact you specifically have the collider map defined to prevent the character from walking into those areas to begin with.

  8. Hey, can we talk somewhere on the forum about this example?
    1) Assets/Tilemaps/Isometric/Colliders/ColliderTiles
    “cube08-a” Collider Type can be changed to Grid, then we will get a nice collider on the Scene/Grid Level/Tilemap – Collider. However, it will be located in a different position than our Tiles. It can be fixed with Tilemap Collider 2D – Offset Y 0,25 or changing the Sprite, because I see on the “Palette_Colliders” is something like a Z position +1 by default.
    2) What about grid based movement? With a change in height (stairway) it is a little bit complicated. We need detect the current Tilemap and change Z position of our player. Is there any other way?

    It would be great to have the official forum thread.

  9. Max Heyder Art (Golden Skull)

    3月 18, 2019 2:34 pm

    Hey folks, amazing article as always.
    Just one thing I noticed:
    my tiles actually use a 128×64 ratio, which is 0.5
    compared to your 128×66 which results in 0.515…which is not correct. :D
    If would be wonderful if you could fix this, because the 0.515 will trigger a lot of OCD (including mine) xD
    Except that: marvelous article <3
    Looking forward to the next stuff about isometric environments
    Greetings

    1. Max Heyder Art (Golden Skull)

      3月 18, 2019 2:47 pm

      However, if you wanna let it stand like that as an example to show the flexibility of the tool to allow for different isometric ratios, its also fine by me. :D
      Just wanted to add that xD

  10. Thanks! Finally something about 2D Isometric.