しばらくObjective-Cをやっていましたが、久しぶりにUnityでゲーム開発をしています。
コンポーネント指向のUnityではMVCやオブジェクト指向がはまらず、勘を取り戻すのにやや苦労しました。
さて...
ゲームに限らず、他オブジェクトに依存する処理は、よくあると思います。
MVCだと「コントローラが、モデルなど他オブジェクトの状態を見て制御」ですが、Unityではしっくりこない気がします。(自分だけ?)
そこで今回、私が実装したレシピをご紹介します。(C#。見やすくするためnullチェックは省略)
例)魔法「イレカワール」
仕様
- 自キャラと、仲間ターゲットキャラの位置が入れ替わる
- 仲間ターゲットキャラが、攻撃中、魔法詠唱中、被ダメージ中、スタン中は、入れ替われない
- 敵キャラとは入れ替われない
実装
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using MagicParams = System.Collections.Generic.Dictionary<string, object>;
public delegate void MagicCallback (GameObject sender, MagicParams userParams);
public class Magic : MonoBehaviour {
/** 入れ替わり */
void Replace (GameObject him) {
// コールバック
MagicCallback replaceRes = (sender, resParams) => {
// 返答OKの場合
if ((bool)resParams ["result"]) {
// 移動
transform.position = (Vector3)resParams ["position"];
}
// 返答NG
else {
// 失敗メッセージ出力などを実装
}
};
// 要求パラメータ
MagicParams reqParams = new MagicParams () {
{"sender", gameObject},
{"position", transform.position},
{"callback", replaceRes},
};
// 入れ替わり要求
him.SendMessage ("ReplaceReq", reqParams);
}
/** 入れ替わり要求 */
void ReplaceReq (MagicParams reqParams) {
// 要求パラメータ
GameObject sender = (GameObject)reqParams ["sender"];
MagicCallback cb = (MagicCallback)reqParams ["callback"];
// 返答パラメータ
MagicParams resParams = new MagicParams () {
{"sender", gameObject},
{"position", transform.position},
};
// 入れ替わり可能かチェック
if (!IsReplacable(sender)) {
resParams ["result"] = false;
if (null != cb) cb (gameObject, resParams);
return;
}
// 移動
transform.position = (Vector3)reqParams ["position"];
resParams ["result"] = true;
if (null != cb) cb (gameObject, resParams);
}
/** 入れ替わり可能か */
bool IsReplacable (GameObject him) {
// himが敵ならreturn false;
// 自分が攻撃中、魔法詠唱中、被ダメージ中、スタン中ならreturn false;
return true;
}
}
以上のように、当事者同士でチェックし合って制御しています。ポイントは↓
- コールバック処理をラムダ式で実装
- パラメータはとりあえずDictionaryにぶち込んで渡す
Magic.csを、魔法を使う/受けるGameObjectに付けて使用します。
イレカワール詠唱時に、Replace(ターゲットGameObject)で呼べば、入れ替わります。
以上、他オブジェクトの状態などに依存する処理のレシピでした。 他にも色々方法はあると思います。ご指摘などあれば、コメントいただけると幸いですm(_ _)m
0 件のコメント:
コメントを投稿