Unityで2Dアクションゲームを作ろう④
Unityを使用した2Dアクションを作成する際に使用した方法やロジックなどを紹介していきます。
※注意 Unity4の頃に作ったものなので、いろいろと古いです。
[Unity_317×90]
Unityで2Dアクションゲームの作成④
前回は以下の内容で進めてきました。
Unityで2Dアクションゲームを作ろう③ ~マテリアルと追従するカメラの設定~
今回はメインのPlayerスクリプトを整理しつつ、ゲーム全体を管理するGameControllerスクリプトを作成します。
今回作成する内容について
Unityで使用できるオーバーライド関数には、Update()が呼び出される直前に一度だけ呼ばれるStart()の他に、
スクリプトが実行された直後に一度だけ呼ばれるAwake()があります。
前回までは全てStart()に記述していましたが、今回から初期化処理はAwake()に、ゲームスタート時のフラグ管理
などはStart()に記述するように変更しました。
また、プレイヤーの移動に関しては、実行環境によって移動速度に差が出ないようにするため、移動に関する記述をUpdate()からFixedUpdate()に変更しました。
※FixedUpdate()は動作が初期設定で毎秒50フレームで固定されており、これは実行環境による差が出ないようになっています。
さらに、前回までの記事からの修正点として、FloorオブジェクトとWallオブジェクトにつけていたタグの名前を『Death』に変更しています。
これは、どちらにぶつかってもゲームオーバーとなるため、タグを分ける必要がなかったからです。
再編したPlayerスクリプト
Player.cs
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float flap = 600f;
public float scroll = 10f;
Rigidbody2D rigidbody2D;
GameObject gameController;
GameObject scoreGUI;
void Awake(){
rigidbody2D = GetComponent<Rigidbody2D>();
gameController = GameObject.Find("GameController");
scoreGUI = GameObject.Find("ScoreGUI");
}
void Start(){
rigidbody2D.isKinematic = true;
}
void FixedUpdate(){
if (GameController.isPlaying == true) {
rigidbody2D.velocity = new Vector2(scroll, rigidbody2D.velocity.y);
}
}
void Update () {
if (Input.GetKeyDown ("space")) {
if(GameController.isPlaying == false){
gameController.SendMessage("GameStart");
rigidbody2D.isKinematic = false;
}
rigidbody2D.velocity = Vector2.zero;
rigidbody2D.AddForce(Vector2.up * flap, ForceMode2D.Impulse);
}
}
void Move() {
if (GameController.isPlaying == true) {
rigidbody2D.velocity = new Vector2(scroll, rigidbody2D.velocity.y);
}
}
void OnTriggerEnter2D(Collider2D col){
if(col.gameObject.tag == "CountZone"){
scoreGUI.SendMessage("AddScore", 1);
}
}
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.tag == "Death"){
gameController.SendMessage("GameOver");
}
}
}
Awake()でコンポーネントやゲームオブジェクトを取得して変数に代入しています。
このように記述することでキャッシュが作成されるため、毎フレームGetComponent<>()しなくて済みます。
フレームごとにGetComponent<>()するような記述は処理が重くなるためお勧めしません。
スタート画面の作成
- スタート画面を作成しましょう。

画面に文字を表示する方法のひとつとして、GUI Textコンポーネントを使用する方法があります。 - 空のオブジェクトを作成して、名前を 『START』 などに変更し、GUI Textコンポーネントを追加しましょう。
追加したら下図を参考にしてパラメータを調整してください。

GUI Textコンポーネントを追加するとTransformのPositionXとYのパラメータは、
画面の上下左右の幅を1とした相対座標に変わります。
Textエリアに文字を入れたのにGameビューに表示されない場合には注意してみてください。 - 色の違う文字を表示したい場合は、もう一つGUI Textコンポーネントを持ったオブジェクトを作成して、同時に表示したいオブジェクトと入れ子にするなどして管理しましょう。

- 1~2と同じ手順で『GAME OVER』のGUIも作成しておきましょう。

- それぞれ作成した文字が同じような位置にある場合、下図のように重なり合って表示されるかと思います。

このように表示されていて問題ありません。
同時に表示するメッセージが重なっていると問題ですが、STARTとGAME OVERは同時に表示することはないためです。あとはスクリプト側からGUI Textの表示/非表示をシーンに応じて切り替えてあげればOKです。
GameControllerスクリプトの作成
ゲームシーン全体を管理するスクリプトを作成しましょう。
このスクリプトではGUI Textの表示/非表示や、ゲーム中かどうかのフラグ管理を行います。
上記のPlayerスクリプトとも連動しているため、ゲームをスタートするまでプレイヤーがスクロールを開始しないような処理や、ゲームオーバーしたらジャンプの操作を受け付けないといった処理が入っています。
GameController.cs
using UnityEngine;
using System.Collections;
public class GameControllerbak : MonoBehaviour {
private GameObject player;
private GameObject start;
private GameObject gameOver;
public static bool isPlaying;
void Awake(){
player = GameObject.Find ("Player");
start = GameObject.Find ("Start");
gameOver = GameObject.Find ("GameOver");
}
void Start (){
gameOver.SetActive (false);
isPlaying = false;
}
void Update (){
if (Input.GetKeyDown("a")) {
Application.LoadLevel("StageSample");
}
}
public void GameStart (){
start.SetActive (false);
isPlaying = true;
}
public void GameOver (){
if (isPlaying == true) {
gameOver.SetActive (true);
isPlaying = false;
player.GetComponent<Player>().enabled = false;
}
}
}
18行目や29行目、35行目で使用しているSetActive()は、trueにするとオブジェクトが有効になり、falseにするとオブジェクトが無効になります。この処理でスタートとゲームオーバーの表示/非表示を切り替えています。
24行目のApplication.LoadLevel()でシーンを再読み込みしています。
シーン名で読み込み直すため、自身が設定したシーン名を直接記述してください。(大文字小文字注意)
この方法は別のシーンに遷移する場合などにも有効です。
37行ではPlayerオブジェクトに追加されているPlayerスクリプトだけを無効にしています。
予め12行目でplayerという変数にオブジェクトだけGameObject.Find()で取得しておき、
player.コンポーネント名.enabled = true で有効化、falseで無効化です。
スクリプトを無効化したため、スペースキーを押してもジャンプできなくなります。
Playerスクリプトの33行目で、GameControllerスクリプトの28行目のGameStart()が、
Playerスクリプトの55行目で、GameControllerスクリプトの33行目のGameOver()が、それぞれ呼ばれています。
スコアの表示の時にも使用した、SendMessageを使用しています。
まとめ
以上がゲームの裏側のフラグ管理です。
これ以降は、プレイヤーの動作や操作に関する処理はPlayerスクリプトに、ゲームの設定やフラグなどに関して
はGameControllerスクリプトに記述していきます。
スタート画面とフラグ管理については以上です。
次回は 障害物の自動生成編 です。
▶
【Unity】3Dアクションゲームを作ろう!#7 ステージの作成(Skybox・落下判定)
▶
【Unity】3Dアクションゲームを作ろう!#8 ステージの作成(スイッチ・扉)
▶
【Unity】3Dアクションゲームを作ろう!#9 プレイヤーのHP管理
▶
【初心者Unity】JsonUtilityクラスでJSONを扱う方法
▶
【初心者Unity】スクリプトからコンポーネントを追加する方法
ゲーム制作関連のオススメ連載リンク
とっても手軽なゲーム制作体験!
Unityゲーム開発基礎
実際のリリースゲームを題材にしたハンズオンゲーム制作連載
実践unityゲーム開発