Hack and Play

プログラミングやCG、ゲーム、コンピュータのネタを投稿していくブログ。不定期更新。

広告

※このエリアは、60日間投稿が無い場合に表示されます。記事を投稿すると、表示されなくなります。

UnityのPlaymakerとC#による状態変移の制御について

2014年01月03日 | CG関連

UnityのAssetStoreで販売している、Playmakerを購入しました。

http://www.hutonggames.com/index.html

このPlaymakerは、スクリプトを一切書かなくても、Unityでゲームロジックが組めるということを売りにしていますが、自分の場合は、普段C#でスクリプトを組んでいるので、そのメリットがちょっと見えづらいという点がありました。

いろいろいじってた結果、Playmakerはゲームロジックのひとつである、状態変移に特化しており、その代わりに非同期処理や複数条件での分岐処理(n-stateを含む)を書くのが難しいことが分かりました。

またC#側ではメリットデメリットが逆転している(状態変移を書くと、Update関数内が変移チェック変数でごちゃごちゃする)ので、これらを使い分けると面白いのではないかと考えたわけです。

 

というわけで、自分の勉強もかねて、C#とPlaymaker両方を使って、状態変移の制御を行う簡単なやり方について考えてみました。
内容の理解度に関しては、一通りPlaymakerを触っている人が対象になります。
アルゴリズムについてですが、

  1. PlaymakerからGameObject(Prefab)のインスタンスを作成する。(1秒ごとに生成するループ)
  2. 生成されたGameObjectは一定時間(ランダム性あり)が来たら自己消滅する。その際にPlaymaker側に消滅したことを知らせる(カウンタを増やす)
  3. Playmaker側は一定数の消滅が来たら、生成ループから外れて、自己消滅する

という構成になっています。

まずはPlaymaker側の設定です。適当な空のGameObjectをHierarchyに追加し名前を"CubeControllerFSM"にし、PlaymakerのFSMを作ります。また、ついでにもうひとつ、"CubeOrigin"という名前の空のGameObjectを作っておきます。
シーンに初めてFSMを作った際の名前は、"FSM"になっていますが、それ以降は変わってきますので、この辺はスクリプトを制御する際に他のFSMと混同しないよう、FSMの名前は意識しておいたほうが良いと思います。

一つ目のActionはCreate Objectになります。このActionは実行時にGameObject(Prefab可)のインスタンスを作成する機能を持っています。Game Objectの箇所には生成したいGameObjectを、Spawn Pointには生成する原点となるGameObjectを設定します。
Store ObjectにはPlaymakerのVariablesの変数と紐付けできますが、増減するものに対しては使いづらいので、今回は無視します。
スクリーンショットでは既にCubeというGameObjectがつけられていますが、後でそのPrefabについて説明します。

二つ目のActionはInt Compareです。これはVariables中のint型の変数が、ある一定の数値未満(Less than)、同値(Equal)、それよりも大きい(Greater than)に、処理を分岐する機能です。

ここでは、IsNotOVERとIsOVERというカスタムEventを作っていますが、ラベル付けの役割だけですので、名前は何でも良いです。
IsNotOVERのほうは、WaitのActionに紐付けされ、IsOVERのほうはDestroy Selfに紐付けされています。
今回は変数にNumOfDestroyという変数を作っています。Variablesタブから変数を作っておきましょう。作ったらInteger1にNumOfDestroyをセットしましょう。

三つ目のActionはWaitです。あまり説明することは少ないですが、Waitは結構重要で、他のActionのLogicのうち、*** Changed系のActionがある場合は、これをかまさないとうまく動かないケースがあります。また、今回はPlaymakerが無駄にインスタンスを生成しないように、Waitを入れています。

このActionは一つ目のCreate ObjectのActionと紐付けされており、ループ処理が行われます。

最後のActionは、Destroy Selfになります。C#で言うDestroy(gameObject)を呼ぶのと同じ機能です。これはそのままなので、画像は省略します。

さて、今度はC#のスクリプト作りです。

名前は何でも良いですが、この記事では"FSMListner"というスクリプトにしています。コードは以下のとおりです。スクリプト自体は、上記の2の機能そのものです。

using UnityEngine;
using System.Collections;
using HutongGames.PlayMaker;

public class FSMListner : MonoBehaviour {

    PlayMakerFSM fsm;
    public string PlaymakerObject;
    public string FsmName;
    public string ParamName;

    float lifetime;

    // Use this for initialization
    void Start () {
        fsm = GameObject.Find(PlaymakerObject).GetComponent<PlayMakerFSM>();
        if(fsm == null && fsm.name != FsmName) {
            Debug.Log("FSMListner: " + PlaymakerObject + " is not found!");
        }
        lifetime = 1.0f + Random.value;
        Vector3 vec = new Vector3();
        vec.x = (Random.value - 0.5f) * 2f;
        vec.y = (Random.value - 0.5f) * 2f;
        gameObject.transform.position = vec;
    }
    
    // Update is called once per frame
    void Update () {
        lifetime = lifetime - Time.deltaTime;
        if(lifetime < 0.0f) {
            if(fsm != null) {
                fsm.FsmVariables.GetFsmInt(ParamName).Value += 1;
            }
            Destroy(gameObject);
        }
    }
}

Start時に自己消滅までの時間を設定し(lifetimeがそれです)、生成位置をランダムに設定しています。また、

fsm = GameObject.Find(PlaymakerObject).GetComponent<PlayMakerFSM>();

の行で、PlaymakerFSMクラス(Playmakerの実体のクラス)から、特定のFSMを抽出できます。
Update関数内では、時間経過による処理のプログラムを書いています。Destroyを呼ぶ前の行の、

fsm.FsmVariables.GetFsmInt(ParamName).Value += 1;

で、FSM内のVariablesにアクセスし、値を書き換える(インクリメント)しています。

スクリプトは保存して、Assetにおいておきましょう。

次にCubeのPrefabとHierarchyについてです。

HierarchyにCubeのGameObjectを作成し、そこに"FSMListener"のスクリプトをD&Dし、CubeをAssetに追加し、Prefab化しておきます。一度Prefab化が終わっていれば、HierarchyからCubeを削除しても大丈夫です。
Inspectorの"FSMListener"の項目に、public変数がありますので、それぞれ、

Playmaker Objectには、"CubeControllerFSM"、
Fsm Nameには、"FSM"、
Param Nameには、"NumOfDestroy"

を忘れずに入れておきましょう、すべて文字列になっていますので、手打ちで文字列を
入力してください。

これが終わったら、再度CubeのPrefabを、Playmakerの一つ目のCreate ObjectのGameObjectにセットしておきましょう。

終わったら、実行して、どんな動作をするか確認しましょう。

実行中はCube(Clone)が生成され、消えては生成され、という具合になり、最後はCubeがすべて消え、CubeControllerFSMも消滅するという挙動になると思います。

さて、今回はPlaymakerとC#両方の操作で互いに影響するコードについて解説をしました。
今後もこのように、互いのメリットデメリットを補完することにより、より楽しいUnityコーディングができるようにいろいろ考えていこうと思います。

ジャンル:
ウェブログ
コメント   この記事についてブログを書く
この記事をはてなブックマークに追加
« MikuMikuNadeNade(仮)につい... | トップ | 表情ジェネレータについて(... »
最近の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。

コメント利用規約に同意の上コメント投稿を行ってください。

数字4桁を入力し、投稿ボタンを押してください。

あわせて読む

トラックバック

この記事のトラックバック  Ping-URL
ブログ作成者から承認されるまでトラックバックは反映されません。