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

 [Oculus Game Jam2013](4)逃げてくクマさんを追いかけてフォロワーを再び!

これで最後です。OculusGameJamで作ったゲームの主な作り方を説明します。

ゲームの流れはこんな感じです。
(1)oculusRiftでPSeye越しに現実風景を見る(AR)
(2)マーカを認識して現実風景をふわっと削除(AR->VR)
(3)フォロワーアイコンを頭上に掲げたクマさん登場(VR)
(4)逃げてくクマさんを追いかけてフォロワーを再び!

今回は(4)を説明します。

(4)逃げてくクマさんを追いかけてフォロワーを再び!


このゲームのルールはとても単純で、時間内にTwitterアイコンをかかげたクマを10体捕まえるだけです。

クマが逃げてく、というのはUnity仮面さんの

Unity仮面が教える! ラクしてゲームを作るためのAssetStore超活用術
Track.2 クマの交通安全ゲームを作ろう! ~「Car Tutorial」「Mecanim Example Scenes」「iTween」編
http://gihyo.jp/dev/serial/01/unity-asset-tech/0002

を、ほとんどそのまま使っています。Unity仮面さん、ありがとうございます。

必要なAssetの入手や設定方法は記事の通りなので省略します。


記事と変えたところは下記です。

[1]カウントダウンタイマーを付けた
[2]クマにタッチすると、クマが消えるようにした
[3]クマにタッチすると、8bitの効果音が鳴るようにした
[4]クマにタッチすると、「あとXクマ」の表示が変わるようにした

ということで、最後はこの[1]~[4]を説明します。

[1]カウントダウンタイマーをつけた

1. 3DTextオブジェクトの設定

まず、3DTextオブジェクトをGameViewに生成し、OVRPlayerControllerの視点から見える位置に配置します。

名前はRemainedTimeとでもします。

次に、これをOVRPlayerController/OVRCameraController/RightCameraにアタッチします。


2. スクリプトの作成

CountDownTime.csを作成し、以下のように記述します。

using UnityEngine;
using System.Collections;

public class CountDownTime : MonoBehaviour {
	private TextMesh timeTextMesh;
	private float playTime = 150.0f;
	private string timeString;

	public bool timeOnFlag = false;
	void Start () {
		timeTextMesh = (TextMesh)this.gameObject.GetComponent<TextMesh>();
	}
	
	void Update () {
	  if(timeOnFlag == true){
		playTime -= Time.deltaTime;
		if(playTime > 0.0f){
			timeString = string.Format("{0:00}:{1:00}:{2:00}",  Mathf.Floor(playTime / 60f), Mathf.Floor(playTime % 60f), playTime % 1 * 100);
			timeTextMesh.text = "time\n" + timeString;
		}
		if(playTime <= 0.0f){
		//	Application.LoadLevel ("GameOver");
		}
			
	  }	
	}
}


timeOnFlagは、(2)でマーカ認識して1秒以上経つとtrueになります。

つまり、AR->VRへ移行したときにカウントダウンが開始します。

次にplayTime変数を

playTime -= Time.deltaTime;

でデクリメントし、そのたびに、

timeString = string.Format("{0:00}:{1:00}:{2:00}",  Mathf.Floor(playTime / 60f), Mathf.Floor(playTime % 60f), playTime % 1 * 100);

で、表示内容を整形しています。数値を右寄せにするなどの処理はstring.Formatメソッドが便利です。


さらに、これを

timeTextMesh.text = "time\n" + timeString;

で3DTextに表示させています。

これをUpdate()の中で繰り返し実行されることで、Playerの目の前ではカウントダウンが確認できます。

シンプルなので、経過時間に関するゲームでいろいろ使えて便利だと思っています。

[2]クマにタッチすると、クマが消えるようにした


実はこれがけっこう悩みました。普通タッチすると何かを起こすには

OnCollisionEnterとか、OnTriggerEnterを使えばよいのですが、

・Playerが近づくとクマが逃げる設定のために、OnTriggerStayを使っている。
->OnTriggerEnterがうまく働かなかった。
(やり方次第で何とかなったのかもしれないが、当日はそれ以上調べる時間がなかった)

・OVRPlayerControllerはCharacter Controllerなので、OnCollisionEnterが使えない


という問題があったためです。


結局はOnControllerColliderHitをOVRPlayerController.csに追加してなんとかなったのですが、最初はうまく動かずちょっと焦りました。

(このとき終了1時間前を切っていたため)


OVRPlayerController.csの末尾に追加した内容は以下です。

RemainedBear remaindBear;
SoundEffectTest soundEffectTest;

void OnControllerColliderHit(ControllerColliderHit hit){
   if(hit.gameObject.name == "RunningBear"){
   soundEffectTest.SendMessage("PlayAudioGetBear");
   remaindBear.SendMessage("GetBear");	
   Destroy(hit.gameObject);
   }	
}


クマオブジェクトはRunningBearとしています。

今回はクマゲット時に効果音もつけたかったので、sound系の処理も入れています。


[3]クマにタッチすると、8bitの効果音が鳴るようにした


実はサウンド関係も初めてでした。なのでざっと調べて最低限音が出るような仕掛けだけを入れました。

//SoundeEffectTest.cs
using UnityEngine;
using System.Collections;

public class SoundEffectTest : MonoBehaviour {
	
 public AudioClip audioClip1;

public void PlayAudioGetBear(){
 audio.PlayOneShot(audioClip1);
}	
	
	
}

書いたのはこれだけです。

Hierarchy Viewに空のオブジェクトSoundTestを作り、そこに、Audio Sourceコンポーネントを付けてから、SoundeEffectTest.csをアタッチしました。

AudioClipのaudioClip1には、それぞれwavファイルをアタッチしました。


にわか勉強ですが、Unityで音を扱うときは、

・音を出すオブジェクト:AudioSourceコンポーネントをアタッチ
・音楽データ:AudioClip
・音を聞くオブジェクト:AudioListenerコンポーネントをアタッチ

という決まりがあるようです。

今回はクマゲットのたびに効果音をPlayerの間近で発生させたかったので、SoundTestオブジェクトをOVRPlayerControllerの子にしてPlayerの移動と同期させました。

※最初はSoundTestオブジェクトを適当な位置に置いてたのですが、そうすると、SoundTestオブジェクトから離れたところでクマゲットしても効果音が小さかったです。


また、効果音には、AssetStoreの「8-bit Sounds Free Pacakge」のPickUp3を使いました。

[4]クマにタッチすると、「あとXクマ」の表示が変わるようにした

これもカウントダウンのときと同じように3DTextをOVRPlayerController/OVRCameraController/RightCameraの子にしてから、以下のスクリプトをアタッチしただけです。

//RemainedBear.cs
using UnityEngine;
using System.Collections;

public class RemainedBear : MonoBehaviour {
	
  private TextMesh scoreTextMesh;
	
  SoundEffectTest soundEffectTest;
	
  public static int totalBear = 10;
  public static int getBear = 0;
  public bool scoreOnFlag =false;
  void Start () {
     scoreTextMesh = (TextMesh)this.gameObject.GetComponent<TextMesh>();
     soundEffectTest = GameObject.Find ("SoundTest").GetComponent<SoundEffectTest>();
  }
	
   void Update () {
    if(scoreOnFlag == true){
	scoreTextMesh.text = "あと\n" +(totalBear-getBear).ToString()+ "クマ\n";
	   if(getScore ==10){
		//Application.LoadLevel ("GameOver");
	    }		
    }	
   }	
    public void GetBear(){
	getBear = getBear + 1;
    }	
}


この中のGetBear()は、[2]のOVRPlayerController.csで呼んだ

remaindBear.SendMessage("GetBear");

のことです。



[1]~[4]を入れると、こんな感じになります。

(再生時間4秒ですが、音が一回だけ出るのでご了承ください)



と、ゲームの主な特徴についてはこんな感じです。


説明することが多かったので、ブログ化に時間がかかってしまいました。


ところでGameJam終了後またPSMoveを使ったゲーム開発を再開しています。

次回のOcufes開催日程は未定ですが、もし近いうちにあるならばなんとか間に合わせたいと思っています。


次はクイズゲームにする予定です。GameJamの他の人のゲームからヒントを得たネタと、自分でやってみたかったネタを組み合わせて、

VR空間ならではのゲームにできたらなと思っています。