その実装を見たところ、比較的単純なものになぜこれほど多くのコードが必要なのか疑問に思いました。
あなたの言うことから、あなたは行動を構成する簡単な方法を望んでいます。ここでの動作は、エージェントによる状態から0個以上のアクションへのマッピングであると私は推測します。これは、C#ラムダを使用して非常に簡単にモデル化できます。例えば:
Action Selector(Func<bool> cond, Action ifTrue, Action ifFalse) {
return () => { if cond() then ifTrue() else ifFalse() };
}
Action Sequencer(Action a, Action b) {
return () => { a(); b(); }
}
ツリーの葉は、状態に適した何かを実行する単純なアクションです。ツリーを実行するだけで「実行」できます。
凝ったものにしたい場合は、このスキームをパラメーター化して、状態を明示的にすることができます。
お役に立てれば。
----補遺----
Jasonは、このアプローチの使用方法の例を求めたので、ここに簡単な「AI」パトロールガードの例を示します(WorldStateは、動作ツリーが評価されるときの環境の記述に対応していると思います)。
Func<bool> ifPlayerIsInSight = () => ...true iff WorldState shows guard can see player...;
Action shootAtPlayer = () => { ...aim guard's weapon at player and fire... };
Func<bool> ifUnderFire = () => ...true iff WorldState shows guard hears player gunfire...;
Action takeCover = () => { ...guard runs for nearest shelter... };
Action walkBackAndForthGuardingDoorway = () => { ...default guard patrol behaviour... };
Action patrollingGuardBehaviour =
Selector(ifPlayerIsInSight, shootAtPlayer,
Selector(ifUnderFire, takeCover,
walkBackAndForthGuardingDoorway));
警備員に何かをさせるには、を呼び出しますpatrollingGuardBehaviour()
。さまざまなサブアクションとテストは、ラムダとしてインラインではなく、適切なシグネチャを持つメソッドとして実装できることに注意してください。他のコンビネータをSelector
およびに追加してSequencer
、たとえば並列アクティビティを行うことができます。