みなさんこんにちは!先日参加したUnityのワークショップ”Unityでゲームを作ろう!vol.1″で制作した内容の復習を兼ねたチュートリアルを今回もお送りします。ワークショップの内容についてはこちらの記事で紹介していますので是非ご覧ください。
まずはワークショップの後半で制作した、迷路をもう一度作ってみたいと思います。
まず最初は[Hierarchy]ウィンドウ > [Create]ボタンをクリック > 3D Object > Plane を選択してシーンに配置。床を作成します。サイズのデフォルトが10m x 10mなのでこのままにしておきます。オブジェクト名は”Floot”に変更。[Inspector]ウィンドウ > Transformの右端にあるアイコンをクリック > Resetを選択して値をデフォルト値にリセットしておきましょう。
次に外壁の作成です。Cubeオブジェクトをシーンに配置します。外壁のオブジェクト名とTransformの値は次の通りです。
床と外壁ができました。
ワークショップの手順では、スタートからゴールまでのルートをCubeオブジェクトを使用してレイアウトする作業を行いましたが、今回は方法をアレンジしてみたいと思います。
そもそもどんな風に迷路のルートをレイアウトしてよいのか?迷路を描く方法について調べてみました。ネットで調べてみてこちらのページ迷路を書けないママが急増中?わずか1分でイラスト迷路を描く方法 OKWAVE ガイド に分かりやすく書いてありました。
分かったのは、正しい迷路はスタートからゴールまでのルートが一つだけ。
…ということだそうです。はじめて知りました!
正しい迷路はスタートからゴールまでのルートが一つだけ。
大事なことなので2回言いました。
というわけで、迷路を書けないママが急増中?わずか1分でイラスト迷路を描く方法 OKWAVE ガイド に掲載されている迷路の作り方について一部内容を引用させてもらいます。
Step1
- 四方の外壁から壁を配置する。壁はグリッドの交点で直角に曲がることができる。
- 壁が他の壁に合流、交差してはならない。
- 壁の先端が、その壁自身に合流、交差してはならない。
Step2
- Step1で配置した壁を分岐または延長する。
- 壁の配置ルールはStep1に準ずる。
Step3
- さらに壁を分岐、延長する。外壁から新たに壁を追加してもよい。
- 壁は何度分岐してもよい。
- 壁の配置ルールはStep1に準ずる。
- グリッドすべての交点に壁が配置されるまで分岐と延長を続ける。
Step4
- スタートとゴールを決める。
- どこにスタートとゴールを設定しても正解ルートが一つだけの迷路になる。
どこにスタートとゴールを設定していも正解ルートが一つだけになる理屈がイマイチ理解できていないですが、手順通りにやってみましょう。まずは四方の外壁から壁を配置します。
配置する壁はCubeオブジェクトのサイズを調整して3種類の長さのオブジェクトを用意。それぞれのオブジェクトのファイル名とスケールは次の通りです。
サイズを調整したオブジェクトを[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”を使用します。
早速ゲームを再生して動きを確認してみましょう。前後には傾きますが左右に傾きません。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でビルドしてみました。ボールがゴール地点に着いた場合のアクションや制限時間などが無いのでゲームの形にはなっていませんが、別の機会に続きをやってみたいと思います。
今回は正しい迷路はスタートからゴールに至る正解ルートが一つだけということを知ることができたのが一番の収穫!?しかし今回作ったような全体が見渡せる視点で迷路ゲームをつくる場合、複数のルートが存在しても途中にトラップ設置するなどしてゴールタイムを競うゲームにしてもいいかもしれませんね。