本記事の記述内容
Unity Game Engineにおけるフラグ管理ライブラリであるS3Engineの構造・実装についてと、またその理由について記す。
Signal
これはフラグ本体である。
フラグを変更するためのvoid Set(bool)と、それを簡便に行うためにvoid On(),void Off()がある。
フラグを読み込むためのbool Read()と読み込みをしたうえで変更をさせるbool DestructiveRead(bool)がある。
これについて異論のある人はいないだろう。
フラグを管理するのだからフラグの実態をしめすためのクラスを用いるのは自然だ。
同様にフラグを管理するのだから、一つの状態の変更とそれを示すこと、それ以外についてはクラスに表現されるべきではない。
なお、SignalとStateにはonTs,onFsという、それぞれOn時・Off時、あるいは状態がアクティブになった際と非アクティブにされる際に発動できるイベントハンドラのような構造があるが、これについては別のエントリで記すことにしたいと思う。
State
Signalとはフラグで、フラグとは状態を示すものである。Stateも状態を示すものである。なぜ二つは違う名前で違う機能を持たせられているか。
実は、すべてをSignalで行うことも可能である。Slotは単純にStateの集合のうちアクティブなものを集合内で一つに管理するだけだし、StateとSignalを関連付けるものは直接的にはなく、間接的なものですら必須ではないものがほとんどだ。
StateとSignalは単にプログラマがインスペクタ上での操作と視認を行いやすくするためにTransform上で親子関係にあるに過ぎない。
しかしながらこれはコードのレベルで見た問題だ。実際の開発はもっと複雑さを帯びているし、操作性と視認性が上がることは生産性に直結していく。
そして一番大事なのは、同じものを示すことができるとしても、表現の方法が違えば、扱う概念をより適切に示すことができるということだ。そのためにSignalは、StateのTransform子要素として配置することが推奨されるし、その配置表現から、StateはSignalより「よりまとまった」概念を示すのにうってつけだということだ。
Slot
Stateの項で説明した通り、Stateはまとまった状態を示す。まとまった状態は、状態によって表現を変えるゲーム上のものにとって、より大きな意味を持つものだ。たとえば歩くとか走るとか。
このまとまった状態を2つ以上同時に取ることは当然あり得ることではある。もちろんあり得るのだが、それは「まとまっていない状態」だとこのライブラリの設計上では捉えている。
つまり状態によって表現されるものがある時点で取れるまとまった状態はただ1つということだ。
この「ある1つの表現物が取れる状態が1つになる」また「表現物を違う状態にして、複数個置ける」ことを可能にするために、Stateをまとめる構造が要る。それがSlotだ。
と言っても、実際のコード上ではSlotは何の管理もしてくれない。Slotはただ、最初だと指示されたStateを、void Start()の呼ばれた時にアクティブにするだけだ。
Transform上でまとまっているというだけで、オブジェクト上ではまとまっているわけではないので当たり前と言えば当たり前だし、実際Stateを複数アクティブにすることもできる。それはライブラリユーザの自由だが、私は推奨しない。
そして、現実にState遷移時にStateのアクティブ・非アクティブを管理するのはFilterだ。
Filter
Signalは状態で、Stateはまとまった状態だと説明した。まとまった状態は、表現されるものにとって1つであることが推奨されることも説明した。
まとまった状態であるStateは1つである、つまり2つ以上のStateの間をアクティブだという情報が移動していくことになる。
そのアクティブ状態を移動させるための構造がFilterだ。
これは、特定のいくつかのSignalが、それぞれに対してライブラリユーザの任意の状態を取った時、現在のStateから目標のStateへアクティブ状態を移動する、という動作をする。
終わりに
簡単にS3 Engineのコア部分の説明をした。これらだけで最小限フラグと状態を表すことが可能だ。
今後はさらに、Signalをより柔軟かつ簡易に変更するためのユーティリティ群について説明していきたいと考えている。
0 件のコメント:
コメントを投稿