読者です 読者をやめる 読者になる 読者になる

Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

CardboardでVRアプリを作ってみる(5)

モバイルVR Particle ゲーム Prefab Point light

はじめに

前回は、敵を撃退するための機能を実装しました。かなりゲームらしくなってきたものの、今はシーンに配置したスケルトンを撃退するだけなので、あっという間にゲームが終了してしまいます。
f:id:tuti107:20160328082503p:plain
今回は、スケルトンの登場処理を追加し、スケルトンを撃退し続ければゲームを続けられる(時間とともに難易度を上げる)ようにします。

出現状態を追加

これまでの要領で、SkeletonAnimControllerに、出現状態(Appear)を追加します。本状態へ遷移させるためのトリガー「Appare」の追加も、以前と同様です。
f:id:tuti107:20160403080702p:plain
状態遷移(矢印)については、

  • Idle→Appear:Appearトリガーを遷移条件に追加する(Has Exit Timeチェックは外す)
  • Appear→Idle:Idleトリガーを遷移条件に追加する(Has Exit Timeチェックは外す)

とします。これも今まで同様です。
次に、Skeleton.csに、出現状態を追加します。以下のコードをSkeleton.csのUpdate()メソッド内に追加してください。

// --- 4/2 add start ---
		if (info.IsName ("Appear")) {
			float t = info.normalizedTime;

			if (t >= 1f) {
				ChangeState ("Idle");
			} else {
				transform.position = new Vector3 (transform.position.x, -1.4f + t * 1.6f, transform.position.z);
			}
		}
		else if (info.IsName ("Idle")) {
// --- 4/2 add end ---
		// if (info.IsName ("Idle")) { // remove 4/2

また、Start()メソッドに以下を追加します。

	void Start () {

		anim = GetComponent<Animator>();
// --- 4/2 add start ---
		ChangeState ("Appear");
// --- 4/2 add end ---
	}

これで、スケルトンの初期状態はAppearとなり、地面からぬっと出現するようになります。出現後Idle状態へ遷移するようになります。

スケルトンの出現場所を作成

次にスケルトンを一定時間毎に出現させる場所を作成します。Hierarchyで右クリック→Create Emptyで、GameObjectを生成し、名前を「Gates」としてください。さらに「Gates」上で右クリック→Create Emptyで、Gates配下にGameObjectを生成、名前をGateとしてください。次に、前回ご紹介したParticle「KY_effects/MagicEffectsFreePack/prefab/energyBlast」を「Gate」までドラッグドロップしてください。これで以下のような感じになるかと思います。
f:id:tuti107:20160403082422p:plain
次に、前回の要領で、このParticleの設定を行います。Positionは(0, -0.8, 0)とし、Play In Awakeのチェックを外します。このParticleはスケルトン出現時に使用します。単に地面から出てくるよりも、よりかっこいい登場の仕方となります。
f:id:tuti107:20160403082730p:plain
次に、上記で作成したGateに、以下のスクリプトを設定します。Gate.csを新規作成し、以下を入力してください。

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

public class Gate : MonoBehaviour {

	public int max = 3;
	public float duration = 30f;
	public float initial = 0f;
	public float durationDelta = 3f;
	public float durationMin = 10f;

	public Player player;
	public GameObject enemyPrefab;
	public ParticleSystem particeSystem;

	private float lastCreated;
	private List<GameObject> enemies = new List<GameObject>();

	// Use this for initialization
	void Start () {
		lastCreated = initial - duration + Time.time;
	}

	// Update is called once per frame
	void Update () {

		if ((Time.time - lastCreated > duration) && enemies.Count < max) {

			lastCreated = Time.time;
			duration -= durationDelta;
			if (duration < durationMin)
				duration = durationMin;

			GameObject obj = GameObject.Instantiate (enemyPrefab);
			obj.transform.parent = transform;
			obj.transform.position = transform.position;
			Skeleton skeleton = obj.GetComponent<Skeleton> ();
			skeleton.gate = this;
			skeleton.player = player;

			particeSystem.Play ();
		}
	}

	public void Remove(GameObject obj) {
		enemies.Remove (obj);
		GameObject.Destroy (obj);
	}
}

また、Skeleton.csに以下通り、gateの追加(冒頭部)、Uodate()メソッドの変更を行います。

// --- 4/2 add start ---
	public Gate gate;
// --- 4/2 add end ---
		} else if (info.IsName ("Dead")) {
			float t = info.normalizedTime;
			if (t >= 2f) {
// --- 4/2 add start ---
				if (gate != null) {
					gate.Remove (gameObject);
				}
// --- 4/2 add end ---
				GameObject.Destroy (gameObject);
			}
		}

次に、スクリプトをGateに設定します。Gateのインスペクタから、Add Component→Gateを選んでください。
Gate (Script)への設定は以下のとおりです。
f:id:tuti107:20160403105655p:plain
Playerは、前回の要領で、インスペクタを二つ表示し、CardboardMain内のPlayer (Script)をドラッグ&ドロップで設定します。Particle Systemには上記でGate配下に追加したenergyBlastをドラッグ&ドロップしてください。
Max, Duration, Initial, Duration Delta, Duration Minには、それぞれこの場所からスケルトンが登場する最大数、登場間隔(秒)、ゲーム開始後最初に登場するまでの時間(秒)、スケルトン登場毎にDurationを何秒づつ短くするか、最低Durationは何秒まで減少するか、をそれぞれ指定します。本設定値を変えたGateをシーン内に複数設置することで、いろいろな場所からいろいろなタイミングでスケルトンが登場するようになります。

スケルトンをPrefab化

上記のEnemy PrefabにはSkeleton@Skinをドラッグ&ドロップでも良いのですが、こうしてしまうと、Gateからの登場に関係なく、一つシーンにスケルトンを配置しておかなければならなくなります。そこで、Skeleton@Skinをシーンから、Projectの適当なフォルダへドラッグ&ドロップしPrefab化します。Prefab化されたSkeleton@Skinは、他のProject内のコンポーネント同様、ドラッグ&ドロップでシーン内やインスペクタ内に配置できるようになります。
f:id:tuti107:20160403110957p:plain
ここで設定されたSkeleton@SkinのPrefabは、Gate.cs内(GameObject.Instantiate(enemyPrefab))にて、Skeleton@Skinの複製を作成するために使用しています。このように、Prefabの複製を利用することで、スクリプトからシーン内に複数のキャラクタを自動生成・配置することが可能です。
Gateを一つ生成したら、これをCopy&Pasteして、複数に増やし、適当な場所に配置してください(上記のMax, Duration等の値を少しずつ変えると良いと思います)。
f:id:tuti107:20160403112853p:plain

Point lightの色を変える

最後に、現状明るすぎる画面を、スケルトンを倒すゲームっぽく、暗い感じに変更します。HierarchyよりPoint lightを選択し、インスペクタより照明の色を変更します。
f:id:tuti107:20160403111744p:plain
以上で、以下のような感じになります。
f:id:tuti107:20160403112007p:plain

まとめ

今回は、スケルトンを登場させる場所(Gate)を作成し、これをシーン内に配置することで、その場所から次々とスケルトンが登場するようにしました。次回は、ライフ・ゲームオーバー・コンティニュー処理を加え、本アプリの完成を目指します。