障害物を作る

次はステージの元となる障害物を作ります。

「障害物を動かす」という考え方

普通、アクションゲームではプレイヤーが動いて、それにカメラが追従することで画面がスクロールします。しかし今回のゲームの場合、プレイヤーキャラは単純にジャンプするだけですし、障害物も一定速度で右から左に流れていくだけでOKです。そこでキャラクターを動かさずに障害物だけを動かすという発想でステージを作ります。こうすればプレイヤーキャラを動かすプログラムやカメラを追従させるプログラムも不要ですし、ステージをスクロールさせる処理も簡略化することができます。ゲーム制作というと大変になりがちですが、一工夫することで手間を大きく省けることがあるのです。

障害物のゲームオブジェクトを作る

まず、床を作った時と同じ要領で障害物のゲームオブジェクトを作ります。「floor」スプライトをシーンの適当な場所にドラッグ&ドロップし、インスペクタで下の図のようにコンポーネントを追加・設定してください(障害物は動かしたいのでRigidbody2Dコンポーネントをつけます)。

障害物のゲームオブジェクトの設定

※追記:Tagを「Wall」に設定してください。

障害物のプログラム

次にプログラムを書きます。「Script」フォルダに「Wall」ファイルを作り、それを開いて下記のコードを記入してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wall : MonoBehaviour {

	[SerializeField]
	float speed = 10.0f;
	[SerializeField]
	float minScaleX = 4.0f;
	[SerializeField]
	float minScaleY = 3.0f;
	[SerializeField]
	float maxScaleX = 6.0f;
	[SerializeField]
	float maxScaleY = 7.0f;

	bool inCamera = false;
	Rigidbody2D rigidBody2D;

	//初期化
	void Start()
	{
		//コンポーネントを取得
		rigidBody2D = GetComponent<Rigidbody2D>();

		//壁の長さをランダムに変更
		float scaleX = Random.Range(minScaleX, maxScaleX);
		float scaleY = Random.Range(minScaleY, maxScaleY);
		transform.localScale = new Vector3(scaleX, scaleY, transform.localScale.z);
	}

	//物理演算
	void FixedUpdate()
	{
		rigidBody2D.velocity = Vector2.left * speed;
	}

	//消去処理
	public void DestroyBlock()
	{
		Destroy(gameObject);
	}

	//カメラ内外の判定処理
	void OnBecameVisible()
	{
		inCamera = true;
	}

	void OnBecameInvisible()
	{
		//一度画面内に入って、また出たときに消去する
		if (inCamera)
		{
			DestroyBlock();
		}
	}
}

プログラムの解説

初期化処理

コンポーネントを取得し、壁の長さをランダムに変更します。AからBまでの範囲のランダムな値を作りたいときはRandom.Range(A, B)を使いましょう。

物理演算

障害物に左向きに変数speedの速さを与えます。

消去処理

障害物自身を消去します。

カメラ内外の判定処理

カメラの範囲に入ったかどうかで処理を行います。OnBecameVisibleはカメラの視界に入った時の処理、OnBecameInvisibleはカメラの視界から外れたときの処理です(※テストプレイのときはシーンビューもカメラとして認識されるので注意してください。シーンビューを縮小している場合、メインカメラの範囲から外れてもシーンビューから外れない限りOnbecameInvisibleは呼び出されません)。

それで今回のゲームではカメラ外に障害物を作るのですが、それが流れて行ってカメラに映り、またカメラ外に出たときに消去するといった処理にしたいです。そこで障害物がカメラに入ったらそのことを変数に記録して、その変数がtrueの状態でカメラから出たらその障害物を消去するという処理にしてあります。

レイヤーと当たり判定の設定

さて、これで障害物の完成かと思いきや、テストプレイしてみると問題が発生します。画面外へ流れていくはずの障害物が、Invisible Wallに引っかかって止まってしまうのです。障害物はプレイヤーに対して当たり判定を持たせたいのですが、Invisible Wallには引っかかってほしくありません。このような場合はどうすればよいでしょうか?

こんなときは各オブジェクトにレイヤー(※ソーティングレイヤーとはまた別のものです)を設定することで問題を解決できます。「Edit」メニューの「Project Setting」→「Tags and Layers」を開いてください。そして「Layer」のところに下の画像のようにレイヤーを設定します。

Unityのレイヤーの設定

次に、物理演算の設定を行います。「Edit」メニューの「Project Setting」→「Physics 2D」を開いてください。ここでは物理演算の設定ができるのですが、その中にレイヤー同士の当たり判定を設定できるところがあります。「Layer Collision Matrix」を下の画像のように設定してください。

レイヤー同士の当たり判定の設定

これで障害物と見えない壁、アイテム(後で追加します)と見えない壁、障害物と床の組み合わせの当たり判定がなくなりました。あとは各ゲームオブジェクトにレイヤーを設定してください。

テストプレイして、壁が引っかからずに画面外に流れていけば成功です。

障害物のプレハブを作る

最後に障害物のプレハブを作りましょう。WallオブジェクトをPrefabsフォルダにドラッグ&ドロップすれば完了です。

次のページ:ステージ生成オブジェクトを作る

コメントを残す

メールアドレスが公開されることはありません。