こんにちは。情熱開発部 プログラム1課の澤です!
1月ももう終わり2月が始まりましたね。私は2Dの横スクロールアクションゲームが好きでどのようにして作られているか調べたところ2Dのステージが簡単に作れる機能を知りました!ということで今回は2Dタイルマップについて紹介していこうと思います。
今回はステージとプレイヤーを作成し、当たり判定を付けてステージ上をプレイヤーが動き回れるようにしようと思います。

目次
使用バージョン
※Unity 2021.3.15f1
※2D Tilemap Editor 1.0.0
2Dタイルマップとは
2DタイルマップはUnity 2017.2から追加され、背景やワールド、ステージをペイントで塗るように描いて作成できる機能です。
ステージを作るまでの流れ
- 画像の用意
- タイルパレット(Tile Palette)の作成
- タイルパレット(Tile Palette)の設定
- タイルマップ(Tile Map)の作成
- ステージの作成
画像の用意
今回は64px*64pxの画像を4つ用意しました。

こちらの画像をUnityにインポートして設定していきます。

Sprite Mode > Pixels Per Unitを64に変更します。
2Dタイルマップではタイル1つ分を1Unitとして扱うため、
幅が64pxのスプライトの場合は64と合わせていきます。
こちらのサイズが画像と合っていないと配置をした時に画像が想定よりも大きくなったり、小さくなるので注意してください。
タイルパレット(Tile Palette)の作成
タイルパレットはステージを作るための画像を管理するツールです。
画像が用意できたのでタイルパレットを作成していきます。

Window > 2D > Tile Paletteからタイルパレットウィンドウを開き

Create New Paletteを選択し、Createボタンをクリックすると作成できます。
タイルパレット(Tile Palette)の設定
タイルパレットが作成できたので次はタイルパレットに画像を設定していきます。

画像をタイルパレットにドラック&ドロップすることで設定できます。
これでタイルパレットは完成です。
タイルマップ(Tile Map)の作成
タイルマップはタイルパレットで管理している画像を配置する場所です。
タイルパレットが完成したのでタイルマップを作成していきます。
HierarchyからCreate > 2D Object > TileMap > Rectangularを選択し
TileMapオブジェクトを作成します。


作成するとこのようにグリッドが表示されます。
ここまで作成できればステージを作成できます!
ステージの作成
準備がすべてできたのでステージを作成していきます。
ウィンドウをSceneビューにして先ほど作成したタイルパレットを使うことで簡単にステージが作成できます!
実際にステージを作成している動画がこちらです。
ゲーム画面でちゃんと作成されているか確認をして完成です!

動画で使っていたタイルパレットの機能紹介
ブラシモード

タイルパレットで選択している画像をタイルマップに配置できます。
ショートカットキーはBキーです。
消しゴムモード

タイルマップに配置している画像を消すことができます。
ショートカットキーはDキーです。
塗りつぶしモード

タイルパレットで選択している画像でタイルマップを埋めることができます。
ショートカットキーはGキーです。
当たり判定をつける
ステージが作成できたので、せっかくなので当たり判定をつけてプレイヤーを動かしてみようと思います。
Hierarchyの先ほど作成したTileMapオブジェクト(Stage)に
AddComponentでTilemap Collider 2Dを追加することで当たり判定をつけることができます。


少し見づらいですが、画像のように各ブロックに緑の枠線が表示されていたら当たり判定をつけられています。

プレイヤーの作成
HierarchyからCreate > 2D Object > Sprites > Squareを選択し
Spritesオブジェクトを作成します。

名前の部分をPlayerに変更し、
ScaleのX,Yを0.5にします。
プレイヤーを移動させたり、ステージと当たり判定を付けたいので
AddComponentでRigidbody 2DとBox Collider 2Dをつけます。

プレイヤーは回転してほしくないのでRigidbody 2Dの
Angular Dragを0にし、Constraints > Freeze Rotation Zを有効にします。

プレイヤーを動かすためにスクリプトを作成します。
スクリプト名はPlayerController.csにします。

こちらがPlayerController.csの中身です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 5.0f;
[SerializeField]
private float jumpPower = 5.0f;
private Rigidbody2D rigidbody2d;
// Start is called before the first frame update
void Start()
{
if (rigidbody2d == null)
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
}
// Update is called once per frame
void Update()
{
if(rigidbody2d == null)
{
return;
}
// 移動
rigidbody2d.velocity = new Vector2(Input.GetAxis("Horizontal") * moveSpeed, rigidbody2d.velocity.y);
// ジャンプ
if (Input.GetKeyDown(KeyCode.Space))
{
rigidbody2d.AddForce(transform.up * jumpPower, ForceMode2D.Impulse);
}
}
}
こちらのPlayerController.csを先ほど作成したPlayerオブジェクトにAdd Componentでつけてあげるとプレイヤーが動くようになります。
実際に確認してみましょう。
プレイヤーが黄色の階段に当たった時にきれいに地面に落ちてくれません。
これは摩擦が原因だと考えられるので摩擦をなくします。
AssetからCreate > 2D > Physics Material 2Dを選択してPhysics Material 2Dを作成します。

作成したPhysics Material 2Dを選択してInspectorを見ると設定できる値が二つあります。
Frictionはどれくらい摩擦があるか、
Bouncinessはどれくらい跳ねるかを設定できます。
今回は摩擦をなくしたいのでFrictionを0にします。

PlayerオブジェクトのRigidbody 2DのMaterialに作成した Physics Material 2Dを設定してあげると摩擦がなくなります。

もう一度動作確認をしてみましょう。
プレイヤーがステージを想定通りに動き回ることができました!
2Dタイルマップを使わない場合とのパフォーマンスの比較
今回は2Dタイルマップを使用してステージを作成しましたが、Spriteだけでもステージが作れるので2Dタイルマップを使用した時と使用してない時では、どちらの方がパフォーマンスが良いのか気になったので調べてみました。
パフォーマンスの測定にはUnityのProfilerを使います。
ProfilerウィンドウはWindow > Analysis > Profilerから開けます。
またCtrlキーと7キーを同時押しでも開けます。

タイルマップ使用時

タイルマップ未使用時

赤い枠線で囲んでいるところがおもに違う場所です。
タイルマップ使用時
Culling 0.03ms
Drawing 0.02ms
タイルマップ未使用時
Culling 0.08ms
Drawing 0.09ms
となっておりタイルマップ使用時の方が処理が早いです。
Cullingが少ないのは
タイルマップ使用時の方がRendererが少ない為Cullingが少ないと考えられます 。 (SpriteRendererではSpriteRenderer1つ1つでCulling判定されるため処理が多くなる)
もう一方のDrawingは、Renderingの詳細を見てみましょう。
タイルマップ使用時

タイルマップ未使用時

こちらも赤い枠線で囲んでいるところがおもに違う場所です。
タイルマップ使用時
SetPass Calls 3
Batched Draw Calls 7
タイルマップ未使用時
SetPass Calls 5
Batched Draw Calls 72
どちらの値もタイルマップ使用時の方が少ないためタイルマップ使用時の方が処理が早いのだと考えられます。
これらの結果からタイルマップ使用時の方がタイルマップ未使用時と比べてパフォーマンスが良いということが分かりました!
最後に
2Dタイルマップを使うことでステージの作成が絵を描いているように楽しく簡単にできました。もし興味を持った方がいれば是非使ってみてください。
最後までご覧いただきありがとうございました!
参考にしたサイト
>Unityのタイルマップを使った2Dマップ作成手順解説!
>Unityのタイルマップによる2Dゲームのパフォーマンスの最適
【免責事項】
本サイトでの情報を利用することによる損害等に対し、
株式会社ロジカルビートは一切の責任を負いません。