Categories: Unity

Unity:ワークショップ「Unityでゲームを作ろう!vol.1」の復習で迷路ゲームをつくる

みなさんこんにちは!先日参加したUnityのワークショップ”Unityでゲームを作ろう!vol.1″で制作した内容の復習を兼ねたチュートリアルを今回もお送りします。ワークショップの内容についてはこちらの記事で紹介していますので是非ご覧ください。

迷路をつくる

まずはワークショップの後半で制作した、迷路をもう一度作ってみたいと思います。

床のモデリング

まず最初は[Hierarchy]ウィンドウ > [Create]ボタンをクリック > 3D Object > Plane を選択してシーンに配置。床を作成します。サイズのデフォルトが10m x 10mなのでこのままにしておきます。オブジェクト名は”Floot”に変更。[Inspector]ウィンドウ > Transformの右端にあるアイコンをクリック > Resetを選択して値をデフォルト値にリセットしておきましょう。

壁のモデリング

次に外壁の作成です。Cubeオブジェクトをシーンに配置します。外壁のオブジェクト名とTransformの値は次の通りです。

  • Wall Back – Position X0, Y0.5, Z-5 / ScaleX10, Y1, Z0.2
  • Wall Front – Position X0, Y0.5, Z5 / ScaleX10, Y1, Z0.2
  • Wall Left – Position X-5, Y0.5, Z0 / ScaleX0.2, Y1, Z10
  • Wall Right – Position X5, Y0.5, Z0 / ScaleX0.2, Y1, Z10

床と外壁ができました。

スタートからゴールまでのルートをつくる

ワークショップの手順では、スタートからゴールまでのルートをCubeオブジェクトを使用してレイアウトする作業を行いましたが、今回は方法をアレンジしてみたいと思います。

そもそもどんな風に迷路のルートをレイアウトしてよいのか?迷路を描く方法について調べてみました。ネットで調べてみてこちらのページ迷路を書けないママが急増中?わずか1分でイラスト迷路を描く方法 OKWAVE ガイド に分かりやすく書いてありました。

分かったのは、正しい迷路はスタートからゴールまでのルートが一つだけ。
…ということだそうです。はじめて知りました!

正しい迷路はスタートからゴールまでのルートが一つだけ。
大事なことなので2回言いました。

というわけで、迷路を書けないママが急増中?わずか1分でイラスト迷路を描く方法 OKWAVE ガイド に掲載されている迷路の作り方について一部内容を引用させてもらいます。

Step1

  • 四方の外壁から壁を配置する。壁はグリッドの交点で直角に曲がることができる。
  • 壁が他の壁に合流、交差してはならない。
  • 壁の先端が、その壁自身に合流、交差してはならない。

Step2

  • Step1で配置した壁を分岐または延長する。
  • 壁の配置ルールはStep1に準ずる。

Step3

  • さらに壁を分岐、延長する。外壁から新たに壁を追加してもよい。
  • 壁は何度分岐してもよい。
  • 壁の配置ルールはStep1に準ずる。
  • グリッドすべての交点に壁が配置されるまで分岐と延長を続ける。

Step4

  • スタートとゴールを決める。
  • どこにスタートとゴールを設定しても正解ルートが一つだけの迷路になる。

内壁のパーツを作成

どこにスタートとゴールを設定していも正解ルートが一つだけになる理屈がイマイチ理解できていないですが、手順通りにやってみましょう。まずは四方の外壁から壁を配置します。
配置する壁はCubeオブジェクトのサイズを調整して3種類の長さのオブジェクトを用意。それぞれのオブジェクトのファイル名とスケールは次の通りです。

  • Wall x1 – Scale X1, Y1, Z0.2
  • Wall x2 – Scale X2, Y1, Z0.2
  • Wall x4 – Scale X3, Y1, Z0.2

サイズを調整したオブジェクトを[Project]ウィンドウにドラッグしてプレハブに変換します。こんな感じです。

スナップ設定

プレハブ”Wall x1″はシーンのグリッドの交点に配置した際に座標値が0.5となるため、スナップ設定を変更しておきます。メニュー:Edit > Snap Settings を選択。[Snap Settings]ウィンドウが開いたら値を0.5に変更します。

マテリアルの設定

標準マテリアルのまま壁を配置すると壁も床も白色で分かりづらいのでマテリアル”Floor”と”Wall”を作成してそれぞれ設定しました。

四方の外壁から壁を配置する

迷路を描く方法の手順を参考に外壁からそれぞれ壁を伸ばしてみます。Ctrlキーを押しながらプレハブオブジェクトを移動すると先ほど設定を変更した通り、0.5単位でスナップします。とりあえずこんな感じで配置してみました。

壁を分岐または延長する

配置した壁から枝分かれする壁を配置します。自分の壁や他の壁と合流、交差しないように注意します。ショートカットCtrlキー + Dキーを使ってシーンのプレハブを複製しながらサクサク配置しました。

すべてのグリッドの交点に壁を配置する

さらに枝壁を追加し、外壁からも新たに壁を追加してすべてのグリッドの交点に壁を配置します。こんな感じになりました。

実際に壁を配置してみた感じでは、スタートからゴールまでのルートが一つだけの迷路を作る際のチェックポイントは次のようになると思います。

壁は一つだけの外壁と接続しているか? → 複数の外壁と接続している場合は壁で閉じられた範囲が発生している。
外壁と接続していない壁がないか? → 接続していない壁がある場合は正解ルートが複数発生している。

迷路をマウスで操作してボールを転がす迷路をつくる

ワークショップではCapsuleオブジェクトをプレイヤーとして配置。用意されたスクリプトを割り当てて矢印キーで操作するという内容でしたが今回はちょっとアレンジ。Sphereオブジェクトをプレイヤーオブジェクトにして、迷路そのものをマウス操作で傾けて転がすようにしたいと思います。

マウスで操作で迷路を操作するためのオブジェクト階層を作成する

まずはマウス操作用のスクリプトを割り当てるEmptyオブジェクトをシーンに用意しましょう。[Hierarchy]ウィンドウ > [Create]ボタン > Create Empty を選択。オブジェクト名を”Rotator”に変更します。。迷路のオブジェクトはすべて”Rotator”の子供にします。[Hierarchy]ウィンドウでみるとこのような階層になります。

マウス操作で迷路を操作するためのスクリプトを割り当てる

それではマウス操作で傾きを操作するためのスクリプトを追加しましょう。メニュー:Assets > Import Package > Utility を選択。インポートされたファイルを[Project]ウィンドウで確認すると色々とスクリプトファイルがあります。この中から”SimpleMouseRotator”を使用します。

[Hierarchy]ウィンドウでオブジェクト”Rotator”を選択しておき、[Project]ウィンドウ > Standard Assets > Utility > SimpleMouseRotator.cs を[Inspector]ウィンドウにドラッグ&ドロップします。

早速ゲームを再生して動きを確認してみましょう。前後には傾きますが左右に傾きません。X軸とY軸方向に回転するのでオブジェクト”Rotator”のZ軸が下方向になるように調整。”SimpleMouseRotator”コンポーネントの値も次のように調整しました。

マウスを上下に移動すると迷路が前後に傾き、マウスを左右に移動すると迷路も左右に傾くようになりました。

ボールオブジェクトをシーンに追加

Sphereオブジェクトをシーンに追加して名前を”Ball”に変更。Scaleの値をXYZそれぞれ0.5に変更して迷路の角に配置。物理挙動を追加するために[Inspector]ウィンドウ > [Add Component]ボタン > Phisics > Rigedbodyを選択してコンポーネントを追加します。マテリアルも追加しておきましょう。

カメラ調整をして動作確認

カメラの位置と角度、画角を調整しておきます。今回は次のように調整しました。

再生ボタンをクリックして動きを確認してみましょう。なんと!ボールが床を突き抜けて落下してしまいます。

ボールが床をすり抜けてしまう場合の回避方法

調べたところ、物理挙動のあたり判定を行うRigedbodyコンポーネントを付けたオブジェクト、今回の場合は”Ball”オブジェクトは、自分自身が停止すると物理挙動処理も一時停止するそうです。つまりボールが停止してあたり判定が行われない状態で迷路を傾けたので床や壁をすり抜けてしまったということになります。

簡単な回避方法は床のオブジェクト”Floor”にもRigedbodyコンポーネントを追加すれば大丈夫ということです。[Hierarchy]ウィンドウでオブジェクト”Floor”を選択。[Inspector]ウィンドウで[Add Component]ボタン> Phisics > Rigedbodyを選択してコンポーネントを追加。Rigidbodyコンポーネントのパラメータは”Use Gravity”のチェックを外し、”Is Kinematic”のチェックを入れておきます。

もう一度ゲームを再生しましょう。今度はボールが停止した状態で迷路を傾けても床をすり抜けません。うまくいきました!

壁の高さが高いとボールが見えにくいので調整しました。しかし迷路を傾けた時にボールが壁を跳び越す恐れがあるのでオブジェクト”Floor”を複製して名前を”Ceiling”に変更。向きを180度反転して見えない天井として設置しました。そして迷路のゴール位置に目印としてCubeオブジェクトを配置して青色のマテリアルを設定しました。

WebGLビルド

というわけでここまでの内容をWebGLでビルドしてみました。ボールがゴール地点に着いた場合のアクションや制限時間などが無いのでゲームの形にはなっていませんが、別の機会に続きをやってみたいと思います。

今回は正しい迷路はスタートからゴールに至る正解ルートが一つだけということを知ることができたのが一番の収穫!?しかし今回作ったような全体が見渡せる視点で迷路ゲームをつくる場合、複数のルートが存在しても途中にトラップ設置するなどしてゴールタイムを競うゲームにしてもいいかもしれませんね。

corevale