しばらく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 件のコメント:
コメントを投稿