tanaka's Programming Memo

プログラミングについてのメモ。

(7)ミスの処理

ボールが落下したら、ゲームオーバーになるようにしよう。ボールの落下は、画面の下にコライダー(Collider)を置いて、それとボールの衝突で検出する。

ミスを検出するためのコライダーを置く
  • 【Scene】ビューで、ゲームフィールドの外まで見えるようにする。

  • メニューから【GameObject】→【Create Empty】を選択して空のゲームオブジェクトを追加する。
  • 作成したゲームオブジェクトの名前を「MissZone」にする。
  • 「MissZone」のインスペクター(Inspector)から【Tag】のボタンをドラッグして、一番下の「Add Tag...」を選ぶ。
  • 【Element 1】に「Miss」という文字を設定して、「Miss」タグを作成する。

  • 【階層(Hierarchy)】ビューから「MissZone」を選択し直して、インスペクターの【Tag】で「Miss」を選択する。
  • メニューから【Component】→【Physics】→【Box Collider】を選択して、ボックスコライダーを「MissZone」に追加する。
  • インスペクターの【Box Collider】の設定を以下のようにする。
    • Is Trigger
      • 物理的に衝突させる必要はないので、処理を軽くするためにチェックを入れる。
    • Size
      • Xを800、Yを100、Zを100に設定。
  • 当たり判定が緑色の四角で見えるようになるので、【Transform】のXを0、Zを0、Yを-400ぐらいに設定する。


左右の枠の高さを延ばす

ミス判定用の衝突物が出来上がった。ただ、今のままだと枠とミスゾーンの間に隙間があって、そこからボールが画面外に逃げてしまう可能性がある。枠のボックスコライダーの高さを大きくして、画面外にボールが逃げないように調整しよう。

  • 【階層(Hierarchy)】ビューから「FrameL」を選択。
  • インスペクターの【Box Collider】の【Size】の【Y】を「1.5」にする。
  • 【階層(Hierarchy)】ビューから「FrameR」を選択。
  • インスペクターの【Box Collider】の【Size】の【Y】を「1.5」にする。

これでボールが画面外に逃げることが無くなる。

ミスの処理

ミスの判定はボールのスクリプトに実装する。ボールがブロックに衝突した時は「OnCollisionEnter()」という関数を使ったが、「MissZone」の【Box Collider】で【Is Trigger】という項目にチェックを入れたため、「OnCollisionEnter()」には「MissZone」との衝突は報告されない。

「Is Trigger」にチェックを入れた場合は「void OnTriggerEnter(Collider other)」という関数が呼ばれる。otherには接触相手のColliderオブジェクトが渡される。

Collisionは物理演算をしたり衝突した相手の形状をとることが出来るため、詳細な判定が行える。反面、実行速度は遅くなる。今回のように跳ね返らせる必要がない場合は「Is Trigger」を設定して、単純に接触したかどうかだけの報告を受け取るのがオススメである。

  • 【プロジェクト(Project)】ビューの「Scripts」フォルダを開き、「CBall」をダブルクリックする。
  • MonoDevelop】が開いたら、一番最後の「}」を見つけて、その上の行に以下のプログラムを追加する。
	/** ミス判定*/
	void OnTriggerEnter(Collider other) {
		if (other.CompareTag("Miss")) {
			Application.LoadLevel("GameOver");
		}
	}
  • 上書き保存する。

プログラムの意味は以下の通り。

void OnTriggerEnter(Collider other) {
  • 【Is Trigger】が「true」のオブジェクトとの接触が報告される関数の定義。
  • 引数「other」に衝突相手のデータが入っている。
if (other.CompareTag("Miss")) {
  • 接触相手のタグ(Tag)が「Miss」かどうかを判定。
Application.LoadLevel("GameOver");
  • 「GameOver」シーンを呼び出す。

実行して、ボールを落としてみよう。ゲームオーバーシーンに移行すれば成功である。

ここまでの「CBall.cs」

using UnityEngine;
using System.Collections;

public class CBall : MonoBehaviour {
	public float INIT_DEGREE = 75f;
	public float INIT_SPEED = 250f;

	// Use this for initialization
	void Start () {
		//shotBall();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	/** ボールを発射する*/
	void shotBall() {
		Vector3 vel = Vector3.zero;
		vel.x = INIT_SPEED*Mathf.Cos(INIT_DEGREE*Mathf.PI/180f);
		vel.y = INIT_SPEED*Mathf.Sin(INIT_DEGREE*Mathf.PI/180f);
		rigidbody.velocity = vel;
	}
	
	/** 衝突コールバック*/
	void OnCollisionEnter(Collision col) {
		if (col.gameObject.CompareTag("Block")) {
			col.gameObject.SendMessage("setDamage");
		}
	}
	
	/** ミス判定*/
	void OnTriggerEnter(Collider other) {
		if (other.CompareTag("Miss")) {
			Application.LoadLevel("GameOver");
		}
	}
}