パックマンライクなゲーム制作の振り返りになります。
ゲームは↓で遊べるので、よければ遊んでみてください。
前の投稿はこちらです。
今回のテーマ
最初のテーマは、マップの作成です。パックマンライクということで、シンプルに全体が真四角なフィールドと障害物だけで制作することにしました。縦21マス×横29マスで、基本的に1マスの通路上の道をキャラクターやモンスターが縦横に移動するだけのイメージです。
床に効果を作ったり、障害物の種類を増やしたり、色々応用出来る部分もありましたが、とりあえず、ここにこだわりはなかったので、時間はかけずシンプルに行くことにします。
ひとまず完成イメージとしては、以下の通りになります。

素材の準備
フリーの以下の素材を使用させていだきました。
- Pixel Art Top Down – Basic(Unity Asset Store)
参考:Unity Asset Storeからのダウンロード方法
一応、Unity Asset Storeからのダウンロード方法を記載しておきます。※上記のPixel Art Top DownはImport済なので、別の素材例になります。
web上からImportする場合の手順になります。
- 「Add to My Assets」を押す

- Acceptを押す

- Open in Unityを押す(unityが開きます)

- Package Managerが開かれているはずなので、Downloadを押す(しばらく待つ)

- importを押す

- importするファイルを選んで、importを押す(基本的にすべてのファイルにチェックが入っているので、そのままimportで問題ないはず)

- Projectフォルダの中にファイルが追加されます。(他のフォルダは作成済のゲームのものです。)

Pixel Art Top Downをダウンロードすると、Cainosというフォルダが出来上がっていると思います。
その中から使用したのは、「Cainos > Pixel Art Top Down > Tile Pallete」にあるタイルマップと「Cainos > Pixel Art Top Down > Texture」のTX PlantにあったTX Bush T6だけです。アセット自体にはもっと多くのマップ素材や動かせるキャラクターもありますので、より複雑なマップも作れると思います。今回は最小限のパーツだけでマップを作ることにしました。
タイルマップで床部分を作成する
さて、ここから実際にマップ作成を行っていきます。unityでマップを作成する場合、タイルマップを使う方法がメジャーなようです。
unityのタイルマップとは何かというと、その名前の通り、画像をタイルのように分割し、分割されたパーツを選択して画面上に敷き詰めていくイメージでUIを作っていく方法になります。

触ったことのある方はRPGツクールのマップの作り方をイメージすると分かりやすいかもしれません。ただし、unityの場合、RPGツクールのようにジャンル特化はしていませんので、細かい設定は自分でやらないといけないです(例えば、今回は触れていないですが、そのままだとキャラクターが通れる通れないなどの区別がつきません)。以下、タイルマップによる床の作成手順になります。
画像を分割してタイルマップを用意する
前述したunityアセットの素材は、最初から分割されたタイルマップが用意されています。(後述のTilemapからすぐに使用可能です)
ですが、理解のために、タイルマップを自分で用意する手順もまとめておきます。
1.画像を用意する
タイルマップにしたい画像を用意します。(サンプルでマップ用ではない適当な画像でやっていきますが、大抵のゲーム素材の場合、32×32で分割しやすいファイルを用意されていると思います。)
(画像を使えばなんでもできるという確認のためにゲームと全く関係ない)ブログ用に取得していたフリー素材の画像を使っていきます。

2.画像をタイルに分割する
- ファイルをプロジェクト内のフォルダに入れます。unityにドラッグ&ドロップでも、フォルダにコピーしてもどちらでも構いません。下記では25351_1の画像をドラッグ&ドロップで入れています。ゲーム作成後のフォルダなので、他にも入っていますが、気にしないでください。

- 画像はタイルに分割する必要があります。そこで、Inspectorで画像を処理していく必要があります。使いたい画像を選択して、Inspectorの項目を画像のように入力・選択します。
ただ、正直言うと、細かい仕様の部分は分かっておらず、参考サイトをそのまま使用しています。ちょっと調べてみようとも思ったのですが、一つ一つが結構細かそうなので、また、時間があったら別で調べてみます。今は、そういうものという前提で設定しています。
デフォルトからの主な変更点は以下の通りです。- Sprite Mode:Multiple
- Pixels Per Unit:32
- Mesh Type:Full Rect

- 「Apply」を押した後に「Sprite Editor」を押して編集画面を開きます。

- 「Slice」ドロップダウンをクリックしてて(もしかすると隠れている場合もあるので、windowを広げると出てきます)、Typeを「Grid By Cell Size」に、Pixel Sizeを区切るサイズ(今回は32×32)に指定します。下の方で分割後のイメージが確認できます。問題なければ、「Slice」を押します。

- 反応が分かりにくいですが、画像が分割されています(パーツごとに選択できるようになります)。Sprite Editorを閉じるときにSaveするかを確認されるので、Saveを選びます。これでタイルの分割は完了です。

- 問題なく終わっていれば、フォルダに入れた画像がパーツごとに確認できます。

3.タイルマップでマップを描く
- タイルマップをゲーム画面上に入れていきます。まずは、Hierarchyで「2DObject > Tilemap > Rectangular」を選択しオブジェクトを作成します。完全な余談ですが、Rectangularは日本語では矩形で「くけい」と読むことを始めて知りました。言葉は難しいですが、要は長方形のことのようです。

- オブジェクト名は適当につけてください(ここでは、Testtilemapとしています)。Sceneビューにマス目のようなものが出来ており。左上の方に「Open Tile Palette」というウインドウも表示されます。「Open Tile Palette」を押します。

- Tile Paletteのビューが開きます(作成済みのTile Paletteが表示されています)。Tile Paletteを選択できるドロップダウンから「Create New Palette」を押します。

- Nameに適当な名前を入れて、Createを押します。Paletteを作成するフォルダを選びます(Palette用のフォルダを用意しておくとよいと思います)。

- 先ほど作成したタイルマップの画像をTile Paletteの画面内にドラッグ&ドロップします。パレットの保存先が出てくるので、先ほど作成したフォルダにパレットの名前をつけて保存します。パレットが出来上がります。

- 後は作成したタイルマップからパーツを選んで、Sceneビューに配置していくだけです。サンプルはマップ用の画像ではないので、コラージュ画像みたいになりますが、マップ用に作られた画像などであれば、マップを作成していくことが可能です。

以上がタイルマップでのマップの用意の仕方になります。最初に書いたように、今回のunityアセットは最初からタイルマップが用意されているので、途中はスキップして、最後のタイルマップからマップを作成するところだけで可能です。
実際のゲームのマップでは、床のタイルマップを使って、縦21マス、横29マスの空間を作ります(この範囲がキャラクターやモンスターの移動可能な範囲になります)。全部ただの緑でもいいんですが、ちょっと寂しいので、タイルマップのパーツを少し変えて装飾を入れています。この辺のデザイン的知識はないので、適当です。

障害物を用意する
障害物はアセットのTX Bush T6を、今描いたマップ上に配置していくだけです。だけなんですが、今回、障害物の数が膨大になってしまい大変なので、プログラムで障害物の場所を指定し、ゲーム開始時に障害物が自動で設置されるような設定をしました。
ソースコードを見てもらうと以下の通りです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public GameObject Obstract;
// Start is called before the first frame update
void Start()
{
int[][] map_generator = new int[][]
{
new int[] { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
new int[] { 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
new int[] { 1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,1,0,1,0,1 },
new int[] { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1 },
new int[] { 1,1,1,1,0,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,1 },
new int[] { 1,1,1,1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1 },
new int[] { 1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,1,1,1 },
new int[] { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 },
new int[] { 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,1,1 },
new int[] { 1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
new int[] { 0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0 },
new int[] { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1 },
new int[] { 1,0,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1 },
new int[] { 1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
new int[] { 1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1 },
new int[] { 1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1 },
new int[] { 1,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,1,1,0,0,0,0,0,0,0,1 },
new int[] { 1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1 },
new int[] { 1,0,1,1,1,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1 },
new int[] { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,1 },
new int[] { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }
};
for (int i=0; i < map_generator.Length; i++)
{
for (int j=0; j < map_generator[i].Length; j++)
{
if (map_generator[i][j] == 1)
{
float i_float = (float)-13.0+i;
float j_float = (float)-10.5+j;
Instantiate(Obstract, new Vector2(j_float, i_float), Quaternion.identity);
}
}
}
// 入口部分に木を置く
Instantiate(Obstract, new Vector2(-11.5f, -3.0f), Quaternion.identity);
Instantiate(Obstract, new Vector2(18.5f, -3.0f), Quaternion.identity);
Instantiate(Obstract, new Vector2(3.5f, -14.0f), Quaternion.identity);
Instantiate(Obstract, new Vector2(3.5f, 8.0f), Quaternion.identity);
}
}
障害物を配置する場所を1、そうでない場所(歩ける場所)を0にして、縦横のfor文を回して障害物を配置します(書き方間違えて、縦が逆になってしまってますが)。このやり方だと、テキストで配置場所を変えるだけで、障害物の場所変更が出来るので、今回のように1つのマップを用意するだけであれば、楽でした。作成したマップの座標に合わせて、細かな座標は修正してください。
けっこうな力業になっているような気もしますが、まあ、多分直接座標をオブジェクトごとに書き直すよりは楽なはず。多分。
なお最後の4行に関しては、範囲外にプレイヤーや敵キャラクターが出ていかないように、入り口を塞ぐ木を配置しています。(マップの範囲外のため、for文とは別で作成しています。)
これをGameManagerとしてScriptを保存しておき、空のGameObjecにアタッチしておき、InspectorのObstractにTX Bush T6をアタッチすれば準備完了です(アタッチの方法など詳細は略)。以下の画像は完成したゲーム画面を持ってきたので、色々と作成済みのものが出てきています。

完成
ということで、マップの完成です。実行してみると以下のようにそれっぽいマップが表示されます。

この中をプレイヤーキャラクターを動かして、モンスターを避けつつ、アイテムを集めてスコアを伸ばす、というゲーム部分を作成していきます。
マップの作成については以上になります。次回はプレイヤーキャラクターやモンスターキャラクターの作成について、書いていく予定です。
コメント