Unityちゃんの障害物ゲームを作る
今回は、連載の第3回で実装したUnityちゃんが走ったり、ジャンプしたりする機能を利用して、「Unityちゃん障害物ゲーム」を作ってみたいと思います。
プロジェクトの作成
Unityメニューの[File]ー[New Project]と選択して「Unity-Project Wizard」画面を表示します。「Project Location」の「Project名」に「UnitychanObstacleGame」と指定して、「Create」ボタンをクリックします。
次に「Asset」の準備をします。同じ「Asset」を別のプロジェクトで利用したことがあれば、それを再利用することもできます。コピー元とコピー先のプロジェクトをそれぞれ起動させておき、コピー元からコピー先の「Project」内の「Assets」フォルダーにドラッグ&ドロップします。ですが、「Asset」がバージョンアップしている可能性もありますので、常に最新の「Asset」を「Import」しておくほうがいいでしょう。今回は、必要な「Asset」を「Asset Store」からダウンロードするようにしています。
Asset Storeから各種コンポーネントのダウンロード
Unityメニューの[Windows]−[Asset Store]と選択して、「Asset Store」にアクセスし、以下の3つのファイルをダウンロードします。
- 「”Unity-chan!” model」
- 「Mecanim Locomotion Starter Kit」
- 「Raw Mocap data for Mecanim」
これらのダウンロード方法については、連載の第3回で解説済みですので、そちらを参考にしてください。さらにUnityちゃんの配置、「Main Camera」の設定、実行時に発生するエラーの回避方法なども解説してありますので、まずはそこまで同じように設定を済ませてください。
今回は第3回までの設定に追加するかたちで、ステージの作成、所要時間の表示、そしてゴールの判定について解説していきます。
ステージの作成
まず、「Hierarchy」の「Create」から「Plane」を配置します。「Inspector」内の「Transform」の「Scale」で「X」を「20」、「Y」を「1」、「Z」を「20」と設定して、「Plane」を広くとっておいてください。次に、Unityちゃんと「Directional Light」を配置しますが、位置は連載の第3回と同じでいいでしょう。「Main Camera」の位置も同様です。「Plane」を広く取ってUnityちゃんを配置すると図1のようになります。
「Plane」に「Texture」を適用する
「Plane」が真っ白のままだと、Unityちゃんが動いている様子がわかりにくいので、「Texture」を適用します。「Project」内の「Unitychan」フォルダー内の「Stage」フォルダーに「Textures」というフォルダーがあり、その中に4点ほど拡張子が「png」のファイルが入っています。今回はそのうちの「unitychan tile6.jpg」を「Hierarchy」内の「Plane」上にドラッグ&ドロップします。すると「Plane」に「Texture」が適用されます(図2)。
これで実行してみると、右上隅に「Change Motion」、「Next」、「Back」と書かれたボタンのようなものが表示されています(図3)。これはUnityちゃんを配置してプレイ画面で実行する際に、いろいろなポーズを試すためのボタンです。今回のようにUnityちゃんをスクリプトで操作する場合は、このボタンは不要ですので、「Inspector」にある「Idle Changer(Script)」を削除して、表示を消しておきましょう。
では、次に障害物の配置とゴールを設定しましょう。
ゴールの設定
まず、「Scene」画面の上でマウスのホイールを使って画面を縮小しておきましょう。次に「トランスフォームツールアイコン(図4)」を用いて、図5のように全体が見えるように位置を調整します。
最初にゴールとゴールエリアを設定します。ここでは「Cube」を使ってゴールを作成していますが、必ずこのようにしなければならないというものではありません。読者自身が、自由にゴールの位置や形状、障害物の配置を決めていただいて構いません。
まず「Hierarchy」の「Create」から「Cube」を選択します。すると「Cube」は「Plane」の下に配置されますので、「Hierarchy」内の「Cube」をダブルクリックして位置を確認し、トランスフォームツール(図4)の左から2番目のアイコンをクリックして3方向の矢印キーを表示させて、Y軸を上方向に引っ張ってください。そして、矢印キーを使ってゴールの位置まで移動させます。
位置を決めたら、ゴールのサイズを「Inspector」の「Transform」にある「Scale」で設定します。まずは「X」に「6」、「Y」に「2」、「Z」に「6」と設定しておきますが、実際にプレイしてみながら調整するといいでしょう。またここで、「Cube」の名前を「Goal」としておきましょう。
次に「Goal」の外見を設定していきましょう。まず「Project」の「Create」から「Material」を選択し、名前を「Red」としておきます。「Inspector」内の「Main Color」を「赤系統色」に指定し、「Cube(Goal)」上にドラッグ&ドロップします(図6)。
この「Goal」の上に「ゴール領域」を設定します。先ほどと同じように「Cube」を追加し、「Inspector」の「Transform」の「Scale」はそれぞれ「X」を「4」、「Y」を「5」、「Z」を「4」に設定し、名前も「GoalArea」としておきます(図7)。
次に、図7の「GoalArea」を選択し、「Inspector」の「Mesh Renderer」の右端の「歯車アイコン」をクリックして表示されるリストの一覧から、「Remove Component」を選択します。すると「GoalArea」が図8のように枠だけの表示になります。
この枠は非表示になっており、実際のプレイ画面では見えません。プレイヤーが「Goal」に上がって、「GoalArea」に入ると「Goal!」と表示されるようにします。なお「GoalArea」の「Inspector」の「Box Collider」にある「Is Trigger」には、必ずチェックを入れてください。このチェックが入ってないとゴールの判定ができませんので、注意してください。
障害物の配置
続いて、障害物を配置していきます。Unityメニューの[GameObject]−[Create Empty]を選択し、「Hierarchy」内に「GameObject」を作成します。名前は「Obstacle」と指定します。
次に「Cube」を追加し、「GameObject(Obstacle)」の上にドラッグ&ドロップして、「GameObject」の子要素となるように配置してください。「Cube」を選択して、「Inspector」内の「Transform」にある「Scale」の「X」の上にマウスカーソルを持っていきます。すると、カーソルの形が「←→」に変わりますので、左右にドラッグすると「Cube」の「X」の値が変更されます。「Y」や「Z」の値も同様です。
Unityちゃんがジャンプで飛び越えられる障害物や、飛び越えられない障害物を、読者の皆さんの好きな位置に配置してください。時々「プレイ画面」で実行しながら配置していくといいでしょう。「Cube」が1個できたら、この「Cube」を選択して右クリックで表示されるメニューから「Duplicate」を選択すれば、複製できます。トランスフォームツールで好きな位置に配置してください。複製した「Cube」は元の「Cube」と同じサイズなので、「Transform」の「Scale」を調整して変更するといいでしょう。この辺りは読者が自由に配置していただいて構いません。筆者は図9のように配置してみました。
障害物にMaterialを設定する
現状では「Cube」が白一色なので、「Cube」に「Material」を設定しましょう。「Project」の「Create」から「Material」を3個追加し、それぞれ名前に「Blue」、「Green」、「Yellow」と指定しておきます。各「Material」を選択して「Inspector」の「Main Color」にそれぞれ、「青系統色」、「緑系統色」、「黄系統色」を指定して、「Scene」上に配置している「Cube」に適当にドラッグ&ドロップしていきます(図10)。
タイムの表示とゴールの判定
このゲームではプレイ中に経過時間を表示しつつ、ゴールしたら「Goal!」と表示して、時間表示を止めるようにします。
まず「Hierarchy」内の「unitychan」を選択し、「Inspector」内にある「Layer」の横の「Default」の上下▼部分をクリックし、「Add Layer」をクリックします。表示される「User Layer 8」に「Player」と入力します(図11)。
再度「unitychan」を選択し、「Inspector」内の「Layer」の「Default」から「Player」を選択します。すると、図12のように「Change Layer」の確認ダイアログが表示されるので、「Yes, change children」をクリックします。
同様に、「Tag」にも「Player」を指定しておきます(図13)。
次に、「Hierarchy」から「GoalArea」を選択し、「Add Component」の「New Script」で「Name」に「GoalArea」、「Language」に「Java Script」を選択して、「Create and Add」をクリックします。すると、「GoalArea」の「Inspector」に「Goal Area(Script)」が追加され、「Script」内の「GoalArea」をダブルクリックするとMonoDevelopが起動しますので、リスト1のコードを入力します。
static var myGoal:boolean; myGoal=false; (1) function OnTriggerEnter(myCol:Collider) { if(myCol.tag=="Player") { myGoal=true; (2) } }
- static型の変数myGoalを宣言し、falseで初期化しておきます。staticは静的変数を表し、そのブロックが終了しても変数値が保持されます。myGoalは他のスクリプトからも利用されるのでstaticと宣言しておきます。
- OnTriggerEnterイベントでPlayerがGoalAreaに入ったかどうかを判定し、GoalAreaに入ればmyGoal変数をtrueにします。
次に「Hierarchy」の「Create」で「GUI Text」を追加します。名前は「msg」と指定します。「GUIText」の「Text」は、空にしておきます。その他「Anchor」に「upper left」、「Alignment」に「left」、「Font Size」に「80」、「Font Style」に「Bold(太字)」、「Color(文字色)」に「黄系統色」をそれぞれ指定します(図14)。
次に、もう一個「GUI Text」を配置します。経過時間を表示するものなので、こちらは名前を「TimeText」とします。「GUIText」の中の「Pixel Offset」で、時間を表示する位置を決めます。「X」に「-500」、「Y」に「200」、そして「Font Size」には「40」と指定します(図15)。
次に「Add Component」で「New Script」を選び、「Name」に「myTimeScript」、「Language」に「Java Script」を選択して、「Create and Add」をクリックします。「Inspector」の「TimeText」に「myTime Script(Script)」が追加されます。「Script」の中の「myTimeScript」をダブルクリックし、MonoDevelopで、リスト2のコードを記述します。
static var time:float; function Start () { time=0; (1) } function Update () { myGoal(); (2) } function myGoal() { if (GoalArea.myGoal==false) { time+=Time.deltaTime; (3) }else{ var msg=GameObject.Find(“msg”); msg.guiText.text=”GOAL!”; (4) yield WaitForSeconds (5.0); Application.LoadLevel(Application.loadedLevel); } var now:int=time; (5) guiText.text=”<Color=red>TIME:” + now.ToString()+”</Color>”; }
- 静的変数timeを宣言し、Start関数の中で「0」で初期化しておきます。
- Update関数からmyGoal関数を実行します。myGoal関数内では以下の処理を行います。
- Playerがまだゴールしていない間は、Time.deltaTimeで、前のフレームと今のフレームの時間的な差分を求めて(単位は秒)、静的変数timeに格納して加算していきます。
- ゴールに到達したら、「msg」というGameObjectをFindで見つけて、そのguiTextに「GOAL!」と表示します。5秒待機した後、初期画面に戻ります。
- 変数nowに経過する時間を代入し、guiTextに文字色を赤にして経過時間を表示します。
動画1が、実際に動かしたようすです。
今回はこれで終わりです。この「Scene」画面をUnityメニューの[File]ー[Save Scene]で保存しておきましょう。
初めてのゲームはいかがだったでしょうか。障害物やゴールの位置は読者の皆さんが自由に決めてください。また、Unityちゃんが走ったりジャンプしたりするコードは全てに共通ですので、これ以後の解説でも使用します。
次回は、Unityちゃんが障害物を破壊するゲームを紹介します。お楽しみに。
【参考文献】
浅野祐一、荒川巧也、森信虎 『Unity4入門 最新開発環境による簡単3Dゲーム制作』 SBクリエイティブ(発行年:2013)