ゼロからのUnity(6)ゲームに基本的なルールを加えてみよう
skill

ゼロからのUnity(6)
ゲームに基本的なルールを加えてみよう

2015.11.19

ent129_img01.jpg

最近はアプリやゲームなど、色々と無料のものが増えてきました。
開発者の善意による無償提供だったり、広告収入で頑張っていたりと理由は様々ですが、無料で使えるmBaaSまで登場し、ネットワーク対応のゲームもコストをかけずに開発出来るようになりました。
(mBaaS: Mobile Backend as a service、アプリやゲームなどでよく使う機能をまとめて提供するサービス。ユーザ管理やリモートPUSHなど、様々な機能を提供している)
筆者も最近無料のmBaaSを利用する機会があり、あまりの便利さに「これホントに無料でいいの?あとで請求来たりしないの??」と不信感さえ覚えてしまいました。 よし、今回はmBaaSについて学びましょう!ぜひそうしましょう!!
・・・すみません、テンションが上がり過ぎました。ゲーム作りの基礎を学んでいる真っ最中でしたね。
何をするにも、まずは基本が大切。ここはグッと堪えて、引き続きゲームの基礎作りを進めていきましょう!
(mBaaSは本当に便利ですので、いずれご説明の機会を設けられればと思います。)

さて、前回はキャラクターを操作出来るところまで進めましたね。
今回はゲームのルールを作っていきましょう。

賀好 昭仁

■ゲームのルールと目的

野球やサッカーなどの勝ち負けがあるスポーツには、必ずルールがあります。
ルールでは、チームの人数、どうやったら得点になるか、試合中にやってはいけないことなど、様々なことが決められています。
また、基本的に得点が高いほうが勝ちとなりますので、「ルールに沿って相手より多く得点を得る」ことが最終目的となります。

同じように、ゲームもルールに沿って目的を達成することでゲームが進行していきます。

(余談)目的の無いゲーム
最近人気のMinecraftなど、明確な目的が無いゲームも存在します。
こういったゲームは全く目的が無いわけではなく、ユーザに遊び場を提供することで、ユーザ自身が「よし、次はこれをやろう!」という目的を作って遊んでいます。
ゲーム開発に慣れてきたら、ゲームの自由度を高めてユーザ自身に遊び方を探してもらうのも面白いかもしれません。

では、このゲームはどんなルールにしましょう?
ダメージを受けずにボスを倒したらクリア、制限時間内に特定のアイテムを取得したらクリアなど、様々なパターンが考えられます。
今回は練習ということで、シンプルに
・足場から落ちてはいけない。落ちたらゲームオーバー
・ゴールにたどり着くことが目的。たどり着いたらステージクリア
というルールにしてみましょう。

■ユーザにメッセージを伝えよう

ゲームオーバーやステージクリアしたときには、その情報をユーザに伝える必要があります。そのためには、何らかの演出を準備する必要が出てきます。
演出には視覚エフェクト・画像・音声など、様々な形があります。

今回はシンプルに、ゴールした際には「STAGE CLEAR!!」、ゲームオーバーの際には「GAME OVER」のメッセージを表示することにします。

■メッセージってどう表示するの?

前回までに画像を配置する方法は学びましたが、文字の表示は今回が初めてでしたね。
文字を画像にして配置する手もありますが、Unityにはテキストやボタンなどを簡単に配置できるUI作成機能が備わっていますので、今回はこれを使ってみましょう。

■UnityのUI作成機能について

1. OnGUI()メソッドを使う
Unityにはフレーム毎に呼ばれるOnGUI()というUI描画用メソッドがあり、この中にUI描画用のコードを書きます。
Unityに古くから備わっている機能ですが、現在はもっと簡単な実装方法があるため、利用する機会は少ないでしょう。(公式でも推奨はされていません)
コードのみで完結するため、デバッグ出力には向いているかもしれません。

実装方法を詳しく知りたい場合は、下記の公式ドキュメントに詳しく記載されています。
http://docs.unity3d.com/ja/current/Manual/GUIScriptingGuide.html

2. UI開発用Assetを使う
NGUIという非常に有名なAssetがあり、昨今のUI開発ツールの定番となっています。
UIパーツをグラフィカルに配置出来るため、前述のOnGUI()と比べて使い勝手は格段に良く、メンテナンスもしっかりされています。
NGUIはAsset Storeからダウンロード可能で、執筆時点ではバージョン2.7は無料(Unity無料版と同じく、前年度の予算または売上が10万ドル以下であれば使用可)となっていて、それ以降のバージョンは有料です。

3. UnityのUIシステム(uGUI)を使う
Unity4.6から、Unityに新しいUI作成機能が実装されました。(別名「uGUI」とも呼ばれています)
これは前述のOnGUI()に代わる機能となり、NGUIと同じようにUIパーツをグラフィカルに配置することができます。
NGUIに比べると歴史は浅いですが、必要な機能はひと通り揃っている印象です。また、オフィシャルの機能のため今後にも期待できそうです。

こちらはぜひ公式ドキュメントに目を通しておきましょう。
http://docs.unity3d.com/ja/current/Manual/UISystem.html

今回は、UnityのUIシステム(uGUI)を使って開発を進めていきます。

■メッセージ表示を実装する

では、実装に取り掛かりましょう。

まずは前回までに作成したGameSceneを開きましょう。
ヒエラルキーで右クリック、UI > Text を選択します。
すると、Canvasというオブジェクトが自動生成され、その中にTextが配置されます。

ent129_img02.jpg

このCanvasは、その名の通りUIのキャンバスであり、描画領域です。
ボタンやメニューなどのUIパーツは、Canvasの中に追加していく形になります。

Canvasのコンポーネントでは画面サイズの設定も可能ですので、スマホ向けゲームを作る場合などにも便利です。
http://docs.unity3d.com/ja/current/Manual/class-Canvas.html

また、Canvasの下にEventSystemというオブジェクトも生成されています。
こちらを使うと、ユーザの入力をイベントとして受け取ったりすることができます。
今回は特に使いませんので、そのままにしておきましょう。

設定を続けます。

Textの名前を「MessageText」とし、キャンバスの中央に配置します。
配置は、インスペクターのRect Transformコンポーネントから行えます。
Pos XとPos Yを0にすると、要素がキャンバスの中央に移動します。

ent129_img03.jpg

アンカー関連の設定など、Pos以外のプロパティも頻繁に使いますので、マニュアルに目を通しておきましょう。
http://docs.unity3d.com/ja/current/Manual/UIBasicLayout.html

文字の変更はTextコンポーネントから行うことが可能です。
TextコンポーネントのTextプロパティを「TEST MESSAGE」、Colorを白にしてみましょう。また、ParagraphのAlignmentで文字の配置を設定できますので、中央寄せを選択しておきます。

ent129_img04.jpg

少し文字が小さいので、Font Sizeを「50」にしてみましょう。
おや?文字が画面に表示されなくなりましたね。

ent129_img05.jpg

デフォルト状態ですと、枠からはみ出た文字は表示されなくなっています。

Rect TransformコンポーネントのWidthとHeightでテキスト枠自体を広げるか、またはTextコンポーネント ParagraphのHorizontal OverflowおよびVertical Overflowを「Overflow」に変更することで文字がはみ出ていても表示させることができます。

ent129_img06.jpg

テキストの配置はこれでOKです。

この状態だと常に画面中央にテキストが表示されますので、MessageTextのインスペクター左上にあるチェックボックスをOFFにしておきましょう。
こうすることでゲームオブジェクトが非アクティブとなり、画面に表示されなくなります。

ent129_img07.jpg

(余談)ゲームオブジェクトを非アクティブにする場合の注意点
ゲームオブジェクトを非アクティブにすると、画面に表示されなくなるだけでなく、ゲームオブジェクトのライフサイクルにも影響を与えます。具体的にはStart()やUpdate()メソッドがコールされなくなります。
また、GameObject.Find("オブジェクト名")で検索してもHITしなくなりますので注意しましょう。

今回はテキストのみ配置しましたが、ボタンや画像なども同じように配置可能です。他にもスクロールビューやドロップダウンなど様々なUIパーツがありますので、色々試してみましょう。

■ゴール地点を作ってみよう

次はゴール地点を作ってみましょう。

キャラクターがゴールしたかどうかの判定は意外とカンタンです。
まずはゴール地点に当たり判定のあるオブジェクトを配置します。
そして、キャラクターがこのオブジェクトに衝突したらゴールと見なすようにすればOKです。

では、早速やってみましょう。
Assets
└Sprite Pack #1 ? Tap and Fly
 └Sprites
  └Background
にあるscene_01_midgroundをゲーム画面にドラッグ&ドロップし、名前をGoalとします。
位置は右端のブロックの上にでもしてみましょうか。
また、少し小さいのでScaleを1.5にします。

ent129_img08.jpg

Goalオブジェクトに衝突判定のためのBox Collider 2Dコンポーネントを付与します。 このままの状態だと、Goalが見えない壁となり、キャラクターがぶつかってしまいますので、Box Collider 2DコンポーネントのIs TriggerプロパティをONにしておきましょう。 こうすることで、Colliderの衝突判定のみ行われるようになります。

ent129_img09.jpg

次に、Assets/Scriptsディレクトリ内にGoalという名前でC# Scriptを新規作成します。このスクリプトにゴールの処理を書いてみましょう。
Goalスクリプトを開き、下記のコードを記入します。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Goal : MonoBehaviour
{
  // MessageTextゲームオブジェクト
  public Text messageText;

  ///
  /// Box Collider 2Dの衝突判定時に呼ばれる
  ///

  ///Other.
  private void OnTriggerEnter2D(Collider2D other)
  {
     // 衝突したのがひよこちゃんかどうか判定
     if (null != other.GetComponent()) {
       // メッセージを変更
       messageText.text = "STAGE CLEAR!!";
       // メッセージを表示する
       messageText.gameObject.SetActive(true);
     }
  }
}

GoalオブジェクトにGoalスクリプトをドラッグ&ドロップします。
インスペクターを見るとGoalスクリプトがコンポーネントとして登録されていて、Message Textのプロパティが表示されているかと思います。
(スクリプトにpublicのプロパティを追加すると、ここに表示されます。Unityのステキな機能です!)

Message TextプロパティにMessageTextオブジェクトをドラッグ&ドロップしましょう。

ent129_img10.jpg

Message TextプロパティにMessageTextオブジェクトが紐付けられました。スクリプト内でmessageTextを操作すると、MessageTextオブジェクトに操作が加わることになります。 紐付け手順を忘れると、実行時にエラーが発生しますので注意しましょう。

これでキャラクターがゴール地点に到達した際、「STAGE CLEAR!!」の表示がされるようになりました。
早速プロジェクトを実行してみましょう。
(動画 https://youtu.be/_xZ0AVN4hBQ

■ゲームオーバーを作る

ゴールが出来ましたので、次はゲームオーバーを作りましょう。

ひよこちゃんが落ちてしまった時にゲームオーバーとなるので、ブロックの下の方に横長の衝突判定用オブジェクトを配置します。手順はゴールとほとんど同じです。

まずはCreate Emptyで空のゲームオブジェクトを作って名前を「GameOver」とし、Box Collider 2Dコンポーネントを紐付けます。Is TriggerのONも忘れずに。
また、横長にしたいので、Box Collider 2DのSize Xを「10」にしておきましょう。

このオブジェクトを足場の少し下に配置しておきます。

ent129_img11.jpg

Assets/ScriptsにGameOverスクリプトを作成し、下記のコードを記入します。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class GameOver : MonoBehaviour
{
  // MessageTextゲームオブジェクト
  public Text messageText;

  ///
  /// Box Collider 2Dの衝突判定時に呼ばれる
  ///

  ///Other.
  private void OnTriggerEnter2D(Collider2D other)
  {
    // 衝突したのがひよこちゃんかどうか判定
    if (null != other.GetComponent()) {
      // メッセージを変更
      messageText.text = "GAME OVER";
      // メッセージを表示する
      messageText.gameObject.SetActive(true);
    }
  }

Assets/ScriptsにGameOverスクリプトを作成し、下記のコードを記入します。

GameOverスクリプトをGameOverオブジェクトのコンポーネントとして追加します。Goalの時と同じように、MessageTextプロパティのひも付けも行いましょう。

これで、ひよこちゃんが落下してしまった際にGAME OVERと表示されるようになりました。
(動画 https://youtu.be/QDO6jdygc0Q

■(おまけ)カメラにキャラクターを追従させる

メインテーマからは外れますが、カメラが固定だとステージの配置も制限されてしまいます。
カメラにひよこちゃんを追従させるには、どうすれば良いでしょうか。

答えは超カンタンです。
ヒエラルキーのMain CameraをHiyokoにドラッグ&ドロップします。
すると、Hiyokoの下にMain Cameraが入ります。
この状態でゲームを実行してみてください。
(動画 https://youtu.be/Fj5SJ0vfj0g

カメラがキャラクターを追従するようになりましたね。
親となるゲームオブジェクトが動くと、子のオブジェクトも一緒に動きます。ゲーム本編・UIどちらでも使えるテクニックですので、覚えておきましょう。

■まとめ

今回学んだUIの作成は、どんなゲームでも必ず使うことになるかと思います。ぜひ習得しておきましょう。
また、練習ですのでゲームのルールはシンプルなものにしましたが、本来は物凄く重要な部分です。構想の段階からしっかり考えておきましょう。

さて、ステージクリア・ゲームオーバーを実装したことで少しゲームっぽくなってきましたね。ただ、今の状態だとスタート地点からゴール地点まで進むだけとなっていて、あまり楽しくありません。

次回は敵キャラクターやアイテムなどを作って、ゲームをにぎやかにしていきましょう。

原稿:賀好 昭仁
qnoteスマホアプリ開発チーム技術主任。PHP・Android・iOS・Unityなど複数のプラットフォームでの開発を行う。
しばしば7匹の先輩猫社員たちにイスを占領される。

この記事はどうでしたか?

おすすめの記事

キャリアを考える

BACK TO TOP ∧

FOLLOW