[Unity]2D牧場ゲームを作ってみる　その２[マップ作成]

# 前置き
子供からの夢で「牧場物語やルーンファクトリーみたいな牧場ゲームを作ってみたい！」と思っていました。
QiitaでUnityを使った2Dゲームはないかと調べたところ、素晴らしい記事を発見しました。

- [UnityでRPGを作るpart2 2Dトップビューのマップと衝突判定](https://qiita.com/_tybt/items/0e9605b7acc955078c64)

こちらの神記事を参考に2D牧場ゲームを作成していこうと思います。

# 前回作成したもの

- [[Unity]2D牧場ゲームを作ってみる　その１[歩行アニメーション]](https://qiita.com/kuro_take/items/15d470dd07f22bd468d4)

# 今回作成するもの

- 1.マップの作成
- 2.マップに衝突判定を設定

## 1.マップの作成

### 1-1.マップの画像を分割

- マップの素材は[マップチップ - ぴぽや倉庫](https://pipoya.net/sozai/assets/map-chip_tileset16/)からお借りしました。時間があったら自分でマップを作成したいと思います。

- ダウンロードした画像を`Sprite Editor`でいい感じに画像を分割します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/dadd125b-7752-3ae1-f02b-c68e3c61d9b1.png)


### 1-2.TileMapとTilePalette

- この2つは、タイルの画像を設定してマップ上にタイルのように敷き詰める機能のことです。

- `右クリック > 2D Object > Tilemap > Rectangular`で新しいTilemapが追加できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/2094f1a1-81e5-7e55-0d47-e3c1f77da0eb.png)

- そうすると、`Grid`というオブジェクトが追加されえその中に`Tilemap`が追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/eb83a4cd-8225-fe5e-1cee-c5989ba8231f.png)

- 次に`Windows > 2D > Tile Palette`を押すと、以下のような画面が表示されます。
- 今は森と洞窟、畑などの画像だけを追加しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/c40e956e-9038-4aee-cfbc-da40079a2b56.png)

- 画像の左上のプルダウンを押すと`Create New Palette`という項目があるので、そして新しいパレットを作成します。
- `Name`は分りやすい名前（今回は`Ground`）、`Grid`と`CellSize`はデフォルトで大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/cc05c363-2d95-bfb8-8b6e-60784855f84e.png)

- 次に先ほど`Sprite Editor`で分割したマップの画像を`Palette`にドラッグ＆ドロップすると、タイルを保存するために、保存先のフォルダを指定する画面がでます。
- とりあえず好きな名前の専用フォルダを作成して選択します。

### 1-3.TileMapの編集

- `Tilemap`から描きたいタイル（画像は芝生）を選択、画像の右上の筆アイコンを選択します。
- （複数の`Tilemap`がある場合は、`Active Tilemap`を切り替えます）
- `Scene`画面に好きなようにタイルを設置していきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/9d19dbaf-845d-753b-c7bb-0e07c16f1e36.png)

- 完成形は上のマップになります。芝生と畑を設置しました。

### 1-4.レイヤの上下関係を設定する

- 以下の順番で、レイヤーの上下関係を設定していきます。（下が一番上になる）
  - 歩くマップのあるレイヤー（map_walk_layer）
  - 障害物のあるレイヤー（map_collision_layer）
  - アイテムの置いてあるレイヤー（map_item_layer）
  - キャラクターが歩くレイヤー（map_char_layer）

- `Inspector`で`Tilemap Renderer`より、`Sorting Layer`の▼を押し、`Add Sorting Layer`を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/faac70a4-8555-2ae2-5f9d-0851b397a6b2.png)

- `+`を押し、Layerを追加した後、名前を変更しましょう（わかりやすい名前なら何でもいいです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/32fcd2d5-f28f-7ed7-cf5f-aedae9d6ea4d.png)



### 1-5.歩ける・歩けないTileを分ける

- 先ほど作成した`Tilemap`に`map_walk`と名前を付けます。
- 新しく`Tilemap`を2つ作成し、`map_collision`と`map_item`と名前をつけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/52334884-7c31-1932-5854-2a9b905535e3.png)

- `map_walk`の`Timemap`には、`Sorting Layer`を`map_walk_layer`と設定しましょう。
  - `map_collision`には`map_collision_layer`、`map_item`には`map_item_layer`と設定しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/50f2805d-f37a-c4de-9173-32642dfc2d42.png)

- 歩けるTilemap`map_walk`を除いた、`map_collision`、`map_item`は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/14ec8acb-8197-4c05-761b-04a40ce952ad.png)


## 2.マップに衝突判定を設定

- 次は、キャラクターや木に衝突判定を設定していきましょう。

### 2-1.衝突判定を設定

- キャラクターには`Box Collider 2D`、マップには`Tilemap Collider 2D`のコンポーネントを追加していきます。

- キャラクターの衝突判定を設定していきます。
- `Box Collider 2D`の`Edit Collider`のボタンを押し、Collider（緑の枠）の大きさを調整しましょう。体の下部ぐらいにしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/5ba03df9-bbcc-c363-0a74-a82f553e19a8.png)


### 2-2.RididBody2Dの設定を変更

- 前回はキャラクターの`Rigidbody2D`の`Body Type`を`Kinematic`に設定しました。
- しかし、`Kinematic`は標準の衝突判定が無効になります。
- ただ`Dynamic`にすると、物理演算が有効になり、キャラクターが画面外に落ちてしまいます。
- `Gravity Scale`を0にすることで落ちなくなります。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/8e318547-b254-461f-7405-ea0d6ea20eb2.png)

- もう一つの設定で、`Freeze Rotation`のZをチェックしておきましょう。
- そうすることで、キャラクターが障害物にぶつかった時に変な挙動をしなくなります（試しにZをチェックしないで動きを確認してみましょう…）

### 2-3.コードを修正

- 最後は前回のコード`MoveController`を修正します。
- このコードで、「山や川にぶつかったら移動させない」みたいな動きができるようです。

```cs
public class MoveController : MonoBehaviour {
    public readonly float SPEED = 0.1f;
    private Rigidbody2D rigidBody;
    private Vector2 input;

    void Start() {
        this.rigidBody = GetComponent<Rigidbody2D>();
        // 衝突時にobjectを回転させない設定
        this.rigidBody.constraints = RigidbodyConstraints2D.FreezeRotation;
    }

    private void Update() {
        // 入力を取得
        input = new Vector2(
            Input.GetAxis("Horizontal"),
            Input.GetAxis("Vertical"));
    }

    private void FixedUpdate() {
        if (input == Vector2.zero) {
            return;
        }
        // 既存のポジションに対して、移動量(vector)を加算する
        rigidBody.position += input * SPEED;
    }
}
```

# 完成
![Videotogif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/16395fae-459b-6ebf-52a6-e83e353bbf6d.gif)



# 次回作成するもの（仮）

- キャラに話しかけたときにメッセージを出す

# 参考にしたサイト

- [UnityでRPGを作るpart2 2Dトップビューのマップと衝突判定](https://qiita.com/_tybt/items/0e9605b7acc955078c64)