脱出ゲームを作ってみる(フラグ管理)
ニコ生で脱出ゲームを作っていたのが面白そうだったので、自分も作ってみた。
【雑談】Unityプロ求む-脱出ゲー作り- (番組ID:lv178561943)
とりあえず動かすだけなら、「フラグ管理」「カメラ切替」「イベント制御」だけで何とかなりそうな印象だったのでそこだけ作った。もう少し拘る場合はイベント発動中にアニメーションさせたり、そういった所が必要かもしれない。実装は大体1時間半くらい。
フラグ管理
SingletonMonoBehaviourで何処からでもアクセス可能なフラグクラスを作った。基本的に挙動はこのクラスから制御する形になる。また別のステージでも汎用的に使えるように文字列アクセスのDictionaryを利用。
intや適当な文字列のフラグを用意する場合、多分ステージ独自のパラメータとして持ったほうが良さそう。
自分のSingletonMonoBehaviourは基本的にDontDestroyOnLoadを付けないので、シーンを切り替えた際にスッキリする。使用する場合はシーンのGameControllerオブジェクトにでもアタッチしておく。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;public class FlagController : SingletonMonoBehaviour
{
public bool this [string key] {
get {
if( !flagDictionary.ContainsKey(key) ){
flagDictionary.Add(key, false);
}
return flagDictionary[key];
}
set {
flagDictionary[key] = value;
if( changeFlagEvent != null){
changeFlagEvent(key);
}
}
}public delegate void EventChangeFlag(string flagName );
private Dictionary
これで下のようなコードを書くと何処からでも触れる
// フラグの設定
FlagController.Instance["フラグ名"] = true;
// フラグ状態の取得
bool flag = FlagController.Instance["フラグ名"]
これを使い、下のようにアイテムがクリックされたら反応するクラスを用意した。このクラスはクリックされるとゲームオブジェクト名のフラグを切り替える。ONは押されたらフラグをtrue、OFFはfalse、ToggleはONとOFFを切り替える。
using UnityEngine;
using System.Collections;public class SwitchFlag : MonoBehaviour
{public enum SwitchType
{
Toggle,
On,
Off
}public SwitchType switchType = SwitchType.On;
void OnMouseDown ()
{
switch (switchType) {
case SwitchType.Off:
FlagController.Instance [name] = false;
break;
case SwitchType.On:
FlagController.Instance [name] = true;
break;
case SwitchType.Toggle:
FlagController.Instance [name] = !FlagController.Instance [name];
break;
}}
}
またFlagController.Instance.changeFlagEventにイベントを登録しておくとフラグが変更された際に呼び出してくれる。(正直ここはSendMessageとかでも良かったかもしれない)
これは、例えばフラグ制御で表示が変化したりイベントが発動したときに使える。例えばフラグのON/OFFで表示が変わるスクリプト。
using UnityEngine;
using System.Collections;public class VisibleFlag : MonoBehaviour {
public bool enableIsVisible = true;
void Start()
{
FlagController.Instance.changeFlagEvent += Handleaction;
Handleaction(name);
}void Handleaction (string changeFlagName)
{
if( name == changeFlagName )
{
if( enableIsVisible )
gameObject.SetActive( FlagController.Instance[name] );
else
gameObject.SetActive( !FlagController.Instance[name] );
}
}
}
ちなみにeventで動かしているので、オブジェクトやコンポーネントを破棄する場合はOnDestroyのタイミングでちゃんとイベントを破棄する実装にしないとメモリリークを起こす。(全体を破棄する場合はFlagControllerが破棄してくれるので問題なし)。なので基本的に破棄ではなく非表示が望ましい。
続く