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

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

脱出ゲームを作ってみる(ゲームイベントの制御)

Unity ゲームの作り方・チュートリアル・サンプル スクリプト

これの続き。
tsubakit1.hateblo.jp

次はなにかイベントがあった際のメッセージを表示する機能を作る。昨日のと合わせると、Stage1まで作れる。

Stage1.gif


メッセージウィンドウの用意

メッセージ表示用の背景、メッセージを表示するTextMeshを用意する。このウィンドウが出たタイミングでは入力が反応しないように、画面全体をColliderで覆う。後はこのオブジェクトをON/OFFしやすいように空のオブジェクト(MessageWindow)にでも入れておく。

スクリーンショット 2014-05-07 21.45.38
作ったウィンドウに下のソースコードをMessageWindowにアタッチする。アタッチ後はTextMeshに先ほど追加したテキストを追加。

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

public class MessageController : SingletonMonoBehaviour<MessageController>
{
public TextMesh textMesh;

void Start ()
{
gameObject.SetActive (false);
}

void OnMouseDown ()
{
gameObject.SetActive (false);
}

}

これで、何かあったときにビューを表示し、画面をクリックしたら消えるウィンドウが出来る。イベント処理中は画面を閉じないように改造する。

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

public class MessageController : SingletonMonoBehaviour<MessageController>
{
private Queue<Action> actionQueue = new Queue<Action> ();
public TextMesh textMesh;

void Start ()
{
gameObject.SetActive (false);
}

void OnMouseDown ()
{
if (actionQueue.Count == 0) {
gameObject.SetActive (false);
} else {
var action = actionQueue.Dequeue ();
action ();
}
}

public static void AddAction (params System.Action[] actions)
{
foreach (var action in actions) {
Instance.actionQueue.Enqueue (action);
}
Instance.gameObject.SetActive (true);

Instance.actionQueue.Dequeue () ();
}

public static void SetText (string text)
{
Instance.textMesh.text = text;
}
}

これで下のような形でメソッドを呼び出すと、イベント発生時に画面全体を停止してメッセージを表示することができる。また、登録したアクションが尽きるまでダイアログが消えない。


MessageController.AddAction (() =>{
MessageController.SetText ("メッセージ");
});


ステージのギミックを用意する

ゲーム内のイベントを用意する。多分これを汎用化するより特定シーン名のクラスを用意した方が楽に作れそうなので、シーン名のクラスを用意する。


using UnityEngine;
using System.Collections;

public class Manager_Stage1 : MonoBehaviour
{
void Start ()
{
MessageController.AddAction (() =>
{
MessageController.SetText ("Stage 1");
},()=>{
MessageController.SetText ("部屋ヲ脱出セヨ");
});
}
}

フラグが変更したタイミングのみ反応するように変更する。イベント登録は前回と同様、起動時にイベントを登録する。作り方はこんな感じ。ChangeFlagValueの引数には変更したフラグ名が入る。下のコードは、"key"フラグがtrueになったタイミングで呼ばれる例。

画面遷移のエフェクトはトランジションを使った綺麗な画面切替・場面転換 - テラシュールブログのやつ。


using UnityEngine;
using System.Collections;

public class Manager_Stage1 : MonoBehaviour
{
// 中略

void Awake ()
{
flags = FlagController.Instance;
flags.changeFlagEvent += ChangeFlagValue;
}
void ChangeFlagValue (string flag)
{
if (flag == "key" && flags ["key"]) {
MessageController.AddAction (() =>
{
MessageController.SetText ("鍵を手に入れた!");
});
}
if (flag == "door") {
if (flags ["key"] && flags ["door"]) {
MessageController.AddAction (() => {
MessageController.SetText ("脱出した");
}, () => {
FadeCamera.Instance.FadeOut (1, () =>
{
Application.LoadLevel (1);
FadeCamera.Instance.FadeIn (1, null);
});
});
}

if (!flags ["key"] && flags ["door"]) {
flags ["door"] = false;
MessageController.AddAction (() => {
MessageController.SetText ("鍵がかかっている…");
}, () => {
MessageController.SetText ("開くには鍵が必要だ");
});
}
}
}
}