半年以上の時が経ってしまいましたが、みなさまお元気でしたでしょうか?
私は割りと元気です。竹橋です。

前回はすでに用意されているものだけを使用してでも簡単にゲームが作れるということがわかりました。
ですが、モンスターの出現しないモンスターハンターやドラクエが面白いわけがなく、やはり細かいゲームのルールや、調整を加えていける方が、楽しいゲームになるはずですね。
ということで今回は、簡単なプログラムを書きながら、あとから難易度調整ができるゲームを作成したいと思います!

ボールよけながらゴールを目指して舞台から落ちたら残念ゲームを作ろう

タイトルだけですべての情報が把握できるかと思いますが、そんなゲームを作っていきたいと思います。

必要な要素を確認してみましょう。

  1. フロア(灰色の床オブジェクト)
  2. 敵(白い丸のオブジェクト)
  3. プレイヤー(白い四角のオブジェクト)
  4. ゲームオーバー判定(フロアのさらに下にある黒い板のオブジェクト)
  5. ゴール判定(敵が出現する箇所にある、白い帯のオブジェクト)

上記でございます。
順番にやっていきましょう。

フロアを作る

これは前回も用意しましたね。
「Hierarchy」パネルの「Create」タブをクリックして、「3D Object」から「Cube」を選択してください。作成後はわかりやすい様に「floor」などリネームしておきましょう。
scaleの値はそれぞれ、「X 10」「Y 1」「Z 20」とします。この上で四角と丸が暴れます。

今回はわかりやすくなるように、色もつけてみました。
「Project」パネル、「Creative」→「Material」を選択し、この素材の色をInspecterパネルで変更します。
Materialを作成します。
Materialの色を変更します

こうして出来上がったマテリアルを、floorオブジェクトのInspectorにドラッグすると、無事に灰色になります。

忘れる前に保存する

ここまでできたら一度保存しましょう。Ctrl + s で保存ができます。
名前をMainとして保存してみましょう。
すると「Main」というファイルがAssets内に現れるかと思います。

これは「シーン」と呼ばれるものです。
その名の通り「場面」です。敵に接触した!穴におちた!など、イベント発生によってこのシーンを切り替えていくことで、ゲームが展開していくという感じですね。
詳しくは後述しますが、今回はMainの他に、ゴールに到達した際の「Goalシーン」と、ステージから落ちてしまった際の「GameOverシーン」を用意してイベントで切り替えていきます。

敵を作りましょう

ステージの端からプレイヤーをステージから落とすために、ランダムで敵がやってきます。
ここからプログラムの出番です!今回はJavaScriptにて作成していきます。

まずはいつもどおりオブジェクトを作成しましょう。
球体にしたいので「Sphere」を配置し、わかりやすく「Enemy」にリネームしておきましょう。
フロアに埋もれてしまっているので、「position」のY値のみ1にして、他はデフォルトでOKです。

敵があたってくる設定をします

いわゆる「当たり判定」を与えます。

①EnemyオブジェクトのInspectorパネル「Add Component」→「Physics」→「Rigidbody」を選択すると、
②のようなパネルが追加されます。「Use Gravity」にチェックが入っていることを確認しましょう。文字通り、重力の概念が与えられます。

Assetsパネルで、「Create」→「Javascript」を選択してください。
JSファイルが追加されます。敵の動きに関するスクリプトなので、「Enemy」とリネームしておきましょう。

これをダブルクリックで開くか、該当の場所に行きファイルを直接開き、プログラムを書いていきましょう。
デフォルトの記述がいくつかありますが、下記のように書き換えてください。
(「function Start ()~」は今回使わないので削除しておきましょう。)

#pragma strict

function Update () {
  transform.position.z -= 0.2;
}

ちなみにこれはpositionのZ値を0.2ずつマイナスする、という命令なのですが、
Enemyオブジェクトに与えるにはどうしたらよいかというと。。
いつものごとく、このjsファイルを対象のオブジェクトにドラッグ&ドロップするのです!
簡単ですね。

ちゃんと動くかどうか確認してみましょう。
Ctrl + P で、実際のプレイ画面が再生されます。

敵をランダム発生させる!

向かってくる敵は多いほど良いですよね。
そんなときは「プレハブ」を使うと便利です!

先ほど作成したEnemyを、「Hierarchyパネル」から「Assetsパネル」へドラッグしましょう。
Hierarchyパネルに残ったEnemyオブジェクトは削除しておきます。

「Ctrl + Shift + N」で、空っぽのGameObjectを作ります。
これをプレハブとして、先ほどのEnemyを大量出現させます。

プログラムを書いていきますので、Javascriptファイルを作成しましょう。
名前は「enemyBox」とします。

#pragma strict

var enemy : Transform;

function Update () {
  if(Time.frameCount % 60 == 0){//60フレームごとに1回
    //さきほど作成したenemyオブジェクトを出現させる。
    Instantiate(enemy, Vector3(Random.Range(-5.0,5.0),1,8), transform.rotation);
  }
}

Vector3(X値,Y値,Z値)で各値の変化量を与えます。
X値にはRandom.Range関数によって-5から5までの、ランダムな数値をセットしています。
これにより、ステージの横幅全体にわたるランダムな敵の出現、という命令をしています。

このjsファイルをプレハブのGameObjectにドラッグドロップします。するとInspectorパネルにEnemyBoxが現れるので、その中の「Enemy」欄に、AssetsにあるEnemyオブジェクトをドラッグドロップします。

ここまでができているかを確認する為に、「Ctrl+P」で再生してみましょう。

ランダムに大量発生しております。
先ほどのjsの記述で、「Time.frameCount % 30」にすると出現頻度は倍になりますし、
enemy.jsの「transform.position.z -= 0.2;」の数字を大きくすると、敵のスピードがアップします。

プレイヤーを作ろう

敵をよけながら、左右前後に動くプレイヤーを作ります。

敵の時と同様にオブジェクトを用意します。プレイヤーはキューブにしましょう。名前はわかりやすく「Player」にします。

ステージの手前をスタート位置にしたいので、Z値を-9に設定しましょう。
衝突判定の為、こちらも同様に「Rigidbody」を設定します。

ユーザーの入力(矢印キー)により、前後左右に動く為のプログラムを書きましょう。
各説明はコメントを参照ください。

#pragma strict

function Update () {//Input.GetAxis関数により、ユーザーからの入力を取得
  var x : float = Input.GetAxis("Horizontal");//左右に動く
  var z : float = Input.GetAxis("Vertical");//前後に動く
  transform.Translate(x * 0.2, 0, z * 0.2);//それぞれX値と、Z値にセットし移動量として0.2をかける
}

これをplayerオブジェクトにドラッグして設定すると動けるはずです!

ゲームオーバー・ゴールの設定をしよう

さきほど少しだけシーンのお話しがでてきました。
今まではMainシーンにて、プレイ画面の作りこみになっていましたが。
ゲームオーバーと、ゴールのシーンを作って、それぞれの条件によって切り替えていけるようにしたいと思います。

シーンを作る

Ctrl + N で、新しいシーンを作ることができます。
とりあえず保存します。適当に名前は「GameOver」としましょう。

カメラと光源以外なにもない。新たなシーンが作成されました。
ゲームオーバーはとても残念なことなので、ゲームオーバー時には残念そうに「残念。。」というテキストを表示することにしましょう。
そんなjsファイルを用意します。

#pragma strict

var style : GUIStyle;//コンポーネントにstyleを調整するGUIが現れる

function OnGUI() {//文字列の表示方法の設定
  GUI.Label(Rect(10, 10, 100, 30), "残念。。", style);
}

GUI.Label関数で、表示させる詳細情報を設定していきます。
第一引数は表示領域の設定です。ここでは幅100px高さ30pxの長方形を、ウィンドウの10pxずつ内側に表示させます。
第二引数は表示させる文字列の設定です。「残念。。」です。
第三引数は装飾の設定です。今回は、GUIStyleを適用します。

このjsファイルは「カメラオブジェクト」にドラッグドロップして設定します。

カメラのInspectorを確認すると、GameOverという項目が追加されています。
その中にある「style」というプルダウンを開くと、色やサイズなど、見た目に関する設定を細かく指定することができます。
今回はフォントサイズを大きくして、残念な色を設定しました。

同じ要領で、Goalシーンも作成しましょう。
ちなみにgoal_scene.jsとして、下記のような中身にしました。
変数名と、テキストを「ゴール!!!」にした箇所以外は先ほどと同じ記述です。

#pragma strict

var style2 : GUIStyle;

function OnGUI() {//文字列の表示方法の設定
  GUI.Label(Rect(10, 10, 100, 30), "ゴール!!!", style2);
}

実行すると、それぞれこのような画面になるかと思います。

・ゴールシーン

・ゲームオーバーシーン

あたり判定でシーンを切り替えよう

これが最後の手順となります。ある条件でゲームオーバーやゴールのシーンに切り替えます。
ゲーム作ってる感ありますね!

ではゲームオーバーから作っていきたいと思います。

例によって、まずはオブジェクトを作成します

ステージから落ちたあとゲームオーバーとしたいので、ステージ下に大きめの板を用意して、それにプレイヤーが当たったらゲームオーバーというルールにしたいと思います。

Mainシーンに切り替えて、オブジェクト作成します。「deadzone」とでもしておきましょう。
「Rigidbody」を追加・大きさや色などはお好みで設定してください。
ここで重要なのは、「BoxColliderコンポーネント」の「Is Trigger」にチェックが入っている事でございます。
これにチェックがはいっていないと、判定されません。
(不具合あったときにこれに気づかず、1時間は無駄に息していた時間がありました)

jsファイルも用意して、こちらも「deadzone.js」としておきましょう。
コードは下記です。

#pragma strict

import UnityEngine.SceneManagement;//シーンを切り替える機能を使うとき必ず呼び出します。

function OnTriggerEnter (collider:Collider){//オブジェクトがぶつかった場合の処理となります。
  if (collider.gameObject.name == "Plane") return;
   SceneManager.LoadScene("GameOver");//"GameOver"はシーンの名称を入れます。
}

これをdeadzoneオブジェクトにドラッグドロップで設定します。

動きを確認してみましょう。
プレイヤーがステージが落ちたあと、deadzoneオブジェクトに触れたタイミングで、「残念。。」の表示がされればOKです。

同様にして、ゴール地点も作成しましょう。
goalオブジェクトと、goal.jsを用意します。
コードの中身は下記です。

#pragma strict

import UnityEngine.SceneManagement;

function OnTriggerEnter (collider:Collider){
  if (collider.gameObject.name == "Plane") return;
    SceneManager.LoadScene("Goal");//"Goal"シーンへ遷移します。
}

Is Trigger のチェックを確認して!
実行してみましょう。うまくいったでしょうか??

最後に

今回はunity ver5.6での記事となりました。
前回から時間が経ってしまって、気づけば、なんとunity2017が出てしまっていました。。
こちらの勉強も時間を見つけてやっていければなと思います!!

Unity初心者として触れてみた感想ですが、ショートカットキーを覚えていけると、かなり間隔的に作成を進められる部分が多いので、楽しみながら制作を進められました!
ツールの使いかたや、js自体も独特の文法だったりで、、覚えることが多すぎて「残念。。」になりかけましたが、最終的には慣れということですね。
引き続きUnityには触れていきたいと思います!

ありがとうございました。