今回は基礎的なスキルから始め、シンプルな迷路ゲームを作ります。見た目はシンプルですが、その背後には基本的なプログラミングとゲームデザインの原則が隠されています。初心者でも大丈夫、複雑なゲーム開発に挫折することなく、確実にゲーム制作のスキルを習得していきましょう。そして次回以降、この迷路ゲームに面白いギミックを追加して、さらにスキルアップしていきます。
完成品を確認
今回つくるものはこんなの!マウスで視点移動、WASD(もしくは上下左右キー)でキャラクター移動。ゴール用の当たり判定に振れるとGOAL表示がでるものにします。
結構シンプルですが
プロジェクト作成
プロジェクトテンプレート
今回はUniversal Render Pipeline対応のゲームにします。テンプレートはURP(3D)を選択してください。
Starter Assets 三人称視点バージョン
ゲームのコアになる部分はアセットで補います。キャラクター操作部分は迷路ゲームとは直接は関係ないため、アセット側で済ませてしまいましょう。利用するアセットは三人称視点のゲームが簡単に作れる「Starter Assets – Third Person Character Controller」一人称のものもあるので間違えないように!アセットを導入後は再起動を促すダイアログが表示されるのでYESで再起動。
動作確認
立ち上がったら一度動かしてみましょう。Assets/StarterAssets/ThirdPersonController/Scenes/Playgroundを開いてください。下図のようなシーンが展開されたらゲームを動かしてみましょう(画面上部の再生ボタン)。移動はWASDキー、視点移動はマウスで行うことができます。ダッシュする場合はShiftキー押しっぱなしで移動。スペースキーでジャンプできます。
フィールドのオブジェクトを非表示にする
既存のオブジェクトを使っても良いのですが、今回はキャラクターのみを利用します。ヒエラルキーのEnviromentを選択して、インスペクターのチェックボックスを外します。こうすることでゲーム内の背景が非表示になります。なにもないところから作っていきましょう。(床ぐらいは残せばよかったと思ったけどね)
ステージ作成
床を作る
このままだとゲームを起動したら下に落っこちてしまいますので、まずは床を作成しましょう。ヒエラルキー右クリック3D Object>Planeから床を作成します。作った直後は位置が変になっていることが多いので、Reset(Position0,0,0)してからScaleを(20,1,20)にして遊べるエリアを広げましょう。余裕がある場合は元々の床で使われていたマテリアルを適応してみましょう。
壁を作る
ゲームで利用する壁を作っていきたいと思います。
壁を作る共通ルール
今回は壁を伸縮させて作成します。ステージの量産を考えると非効率ではありますが、まずは遊べるものを作りましょう。3D Object>Cubeを作成します。調整方法は主に2つ。
- スケール(x,z)のみを利用して、壁の横幅等を調整する
- z方向にスケールし、Rotation : Yを回転させる
いずれの方法でも構いませんが、今回の共通ルールとして
- Position.y座標は0を基準にする
- Scale.y縦方向の大きさは5にする
以上に気をつけつつ、外壁と内壁を作りましょう。
外壁
まずはレベルの大きさを決める外壁を作成します。今回はScale:20を基準としたステージを作成します。下図は私が作成したサンプルになります。
各壁の主要なパラメータ
壁の位置 | 座標 | スケール |
---|---|---|
右 | 10,0,0 | 1,5,20 |
左 | -10,0,0 | 1,5,20 |
上 | 0,0,10 | 20,5,1 |
下 | 0,0,-10 | 20,5,1 |
ちなみにコーナーはこんな感じに凸凹したままになってます。
内壁
外壁の要領で、迷路部分になる内壁を作成します。私の方では上から見下ろして、右下がゴールになるつもりで迷路を作って見ました。
オススメの編集方法について
各壁をインスペクターの数値を利用して調整するのは少し大変です。今回は動くものを作るのが目的ですので、細かい数字調整は行わずに作って見ましょう。そのための簡単な方法として、私のやり方を少し共有。
- シーンビューの右上:緑色のコーンをクリックして、上から見下ろした状態にする
- 三TOPに切り替える:水平投写に切り替わり、奥行きがなくなるため調整しやすくなります。
- 壁になるオブジェクトを選択した状態で、Rectツールに切り替える
- シーンビュー内で調整したい壁を選択し、位置・大きさ調整を行う
- Ctrl+Dで複製をし、そのまま次の壁を調整する
ゴールを作る
あとはゲームクリアのためのゴール地点を作成します。
ゲーム内
基本的には壁と同じCubeを使いますが、いくつか設定が変わります。縦の大きさは0.5に変更。私のサンプルではx,zを2.5に変更していますが、皆さんの作った迷路の大きさに合わせて調整してください。もう一つ重要な変更として、BoxColliderのIsTriggerにチェックを入れてください。この変更はゴールのみに行うことに注意してください。あとは見やすくするために、マテリアルを変更しておきましょう。Floorのマテリアルがあった場所のGridOrange_01_Matをセットしてください。
UI
ゴール時に、UIでテキストを表示させましょう。ヒエラルキー何も無いところ右クリック>UI>Panelを追加します(右クリックできない場合は左上のプラスボタン)。作られたPanelを右クリックして、UI>Text – Text Mesh Proを追加(Import TMP Essential)。Alignmentを上下方向:中央・左右方向:中央にセットして、Textに「GOAL」と入力して、満足するSizeに変更してください。文字が折り返してしまう場合、Wrapping:Disableに変更すると直ります。あとは色とか好きなのに変えておくと良いですね。
必要なソースコードを書いて完成
一つにまとめることも可能ですが、今回は2つのスクリプトに分けて作成します。スクリプトファイルはAssets/Scriptsフォルダを作り、その中に作成してください。イベントの使い方は少し難しいかもしれませんが、ソースコードあってれば動くので今回はこれで!
MazeManager
ゲーム開始直後にパネルを非表示にして、「ゴールしました!」と誰かが主張したタイミングで非表示にしたパネルを再表示させます。後ほどインペクターに対象のパネルをセットする作業があることに注意してください。
using UnityEngine;
using UnityEngine.Events;
public class MazeManager : MonoBehaviour
{
[SerializeField] private GameObject panel;
public static UnityEvent OnGoal = new UnityEvent();
private void Awake()
{
panel.SetActive(false);
OnGoal.RemoveAllListeners();
OnGoal.AddListener(() =>
{
panel.SetActive(true);
});
}
}
MazePlayer
ゴールの当たり判定に触れたタイミングで、「ゴールしました!」と主張するスクリプト。キャラクター制御等は他のプログラムに任せておきましょう。Triggerモードで当たったら何でもかんでもゴールだと思い込むスクリプトになっているので、その点に注意してください。
using UnityEngine;
public class MazePlayer : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
MazeManager.OnGoal.Invoke();
}
}
シーン内にセットアップ
各スクリプトをセットします。
基本的にどこでもOKです。今回は空のGameObjectを作成(MazeManager)し、そこに貼り付けましょう。貼り付けたらインスペクターのpanelにPanel(Goalのテキストの親のオブジェクト)をセットしてください。
MazePlayerはキャラクターであるPlayerArmatureのGameObjectに貼り付けてください。こちらのスクリプトは位置が重要になります。かならずPlayerArmatureに貼り付けましょう!!!
動かして確認
あとはちゃんとゴールでGOAL表示が出たらOK!
コメント