【Procedure Treeの作成】
Object WindowのCharacter > Packageより、AI Packageを新規作成します。
IDには作りたいPackageにふさわしい名前を入力。
スペルミスってますが……。
ここでは「パトロールしながらアイテムを拾う」行動を作っていきます。
「アイテムを拾う」行動は既存のTemplateがあるので、それをベースに改造していく方法をとります。まずはPackage Templateの項目から"Acquire"を選択。
"Acquire"を選んだ直後。
Templateが読み込まれて、「Public Package Data」や「Procedure Tree」に情報が入りました。
"Acquire"は、指定された場所で指定されたアイテムを探して取るPackageです。「Public Package Data」の項目を見ると想像がつきますが、アイテムを取得する際に、「盗みを許可する」「スリを許可する」「殺してでも奪い取る」などのオプション設定をつけることができます。
Procedure Treeを見ることで、"Acquire"Packageを構成する行動が分かります。
上から順に読んでいくと、"Procedure: Travel"で指定された場所(アイテムを探す場所)へ行き、さまよいながら"Procedure: Find"で目的のアイテムを探します。そして見つけたアイテムを"Procedure: Acquire"で取得します。
Procedureは、AI Packageを構成する行動の最小単位です。30種類程度あります。色々なTemplateを読み込んでProcedure Treeを確認すると分かりますが、このProcedureの組み合わせで様々な行動が実現されています。
それでは改めてProcedure Treeの作成に入ります。
先ほどの状態からPackage Templeteを「None」に変更すると、暗転していたProcedure Treeが編集可能になります。ここで一度OKボタンを押してAI Packageを確定します。
実はこの状態では、Templateから読み込んだ「Public Package Data」の項目全てが表示されているわけではありません。
OKした後、再度Packageを開くと先ほどなかった項目がいくつか現れているかと思います。
Publicに "N" が入っている項目です。これらはTemplate側でのみ決定され、Templateを使用するPackageからは値を編集できない設定になっているものです。基本的に、編集されるとAIがうまく動作しなくなる項目や、編集の必要がない項目が隠されています。今回はTemplateを自作するので、こういった項目もいじっていきます。
CK wikiでは"Procedure: Wander"を"Procedure: Patrol"に変更するだけですが、ここでは説明のために"Procedure: Acquire"以外全部消しました。
新しいProcedureを追加するには、親になるBranchを選択して右クリック。New Procedureを選びます。
Choose Procedureという小窓が開きます。
Procedureは"Travel"を選択。
Use existing data if availableという項目にチェックが入っているのを確認します。これはProcedureが必要とするパラメータを、新たに「Public Package Data」へ追加するかどうかの設定です。今回はTravelに必要なパラメータ候補がすでに「Public Package Data」に存在するので、チェックを入れたままにしておきます。ちなみにチェックを入れていても、必要なパラメータが「Public Package Data」にない場合は、勝手に追加してくれます。
OKします。
"
Procedure: Travel"が子要素としてツリーに加わりました。
これを選択すると、右の「Selected Procedure」という欄に、ProcedureのTypeと、動作に必要なパラメータの一覧が出ます。
"Procedure: Travel"のパラメータは3つ。"Destination(目的地)"のみ、「Public Package Data」から自動的にTypeが一致する項目が割り当てられています。残り2つは空白です。
Procedureは、すべてのパラメータを「Public Package Data」で決める必要はありません。いくつかのパラメータは、設定がなければProcedure側でデフォルトの値を使用します。ただしProcedureを動かすのに絶対必要なパラメータもあります。
"Procedure: Travel"は、"Destination"が必要不可欠と思われます。他は特に設定しなくてもよさそうなのですが……。パラメータが足りないと、CKがエラーを出したりProcedureが稼動せずNPCが棒立ちになったりするので、すべてのパラメータに具体的な値を用意してあげるのが無難です。
設定したい項目を選択して、Input Dataから「Public Package Data」の設定を割り当てます。
すでに最適な項目が存在するので、それを選ぶだけ。
こうなります。
"Procedure: Travel"を追加したのと同じ要領で、New Branch。新しいBranchを追加します。
"Stacked"というのが追加されるので、これを選択して右側の「Selected Branch」欄で"Simultaneous"というのに変更します。時々プルダウンの選択欄に同じBranchが複数並ぶときもありますが、どれか1つ選べば大丈夫です。
Simultaneousを選択して、New Procedure。
"Procedure: Find"を追加します。各パラメータに「Public Package Data」の項目を適切に割り当てます。
終わったら、同じBranchに"Procedure: Patrol"も追加します。
追加した直後。
各パラメータを埋めたいところですが、"RideHorseIfPossible"はTravelで設定したのと同じ項目を当てはめるとしても、その他の"PathStart"などに相応しい項目がありません。
「Public Package Data」にPatrol用の新しい項目が必要になります。
「Public Package Data」の欄内で右クリックしてNew。<none>という新しい項目が一番下に追加されるので、それを選択して右のSelected Package Dataで名前と値のTypeを決めます。
まずは"PathStart"の項目を作ることにします。
Procedureが必要とする"PathStart"の値のTypeは"target"です。これと一致する「Public Package Data」の値のTypeは"SingleRef"と"ObjectList"。ここでは"SingleRef"にします。
新規追加した項目は、"Patrol Start"という名前にしました。
下のパラメータで、"PathStart"のInput Dataを確認します。値のTypeが一致していれば、候補として追加した項目が出てくるはずです。
あと、"PointRadius"という"Float"タイプの項目がこっそり増えているかと思います。これは"Procedure: Patrol"を追加したときに、自動的に付け加えられたもの。Procedureを動かすのに必須な値かつ、「Public Package Data」にType "Float" の項目がなかったためです。
同様にして、新しい項目"Start At Nearest?"、"Repeatable?"、"Static Pathing?"を追加します。
できたら、各項目をパラメータに割り当てていきます。
次に、"Procedure: Acquire"をドラッグ&ドロップでツリーの一番下へ移動させます。
"Procedure: Acquire"をSimultaniousの中に入れないように気をつけてください。Branchは一度閉じておくと、動かしやすいです。
最後に、最上位のSequenceを選択して、右欄「Repeat When Complete」にチェックを入れます。"Procedure: Acquire"が終了したら、また最初からProcedureTreeを繰り返してくれます。
Procedure Treeの動作はこんな感じ。
最上位のBranchはSequenceなので、子要素を上から順番に実行していきます。
Simultaneousにて、"Procedure: Find"と"Procedure: Patrol"を同時実行することで、「パトロールしながらアイテムを探す」行動を実現しています。このBranchは、探しているアイテムが見つかった時点で"Procedure: Find"が終了し、Branchを抜けます。
そして最後の"Procedure: Acquire"が実行されて終了。最上位のSequenceにリピート設定をしたので、またパトロールしながら探す行動を繰り返します。
一番最初の"Procedure: Travel"で「目的地まで移動」と書いていますが、目的地"Search Loc"は"Procedure: Find"の検索ロケーションと同じデータを使用しているため、実質ほとんど機能しないようになっています。このProcedureはDeleteしてもいいかもしれません。
これで「パトロールしながらアイテムを拾う」Packageの作成は完了です。
このままでも十分使えますが、より汎用性を高めるためにTemplateに作り変えてみましょう。
【Templateにする】
Templateにするには、ウィンドウ右上のPackage TypeからPackage Templateを選ぶだけです。
これでこのPackageはTemplateとして使用できるようになりました。
次に「Public Package Data」の設定。
各項目を見ると、右欄に「Public」というチェックボックスが追加されています。
チェックをはずすと、その項目はTemplateを使用するPackage側には公開されないPrivateデータになります。Procedure Treeを稼働させる上で変更されると困る項目や、変更する必要のない項目などはチェックをはずします。
今回Publicのフラグはあんまりいじりません。Package側で表示させたくない項目はすでにチェックがはずされています。
新たに追加した項目"Repeatable?"のみチェックをはずし、ValueのTrueにチェックしておきます。これで"Procedure: Patorol"は指定されたPatrolマーカーを延々と往復するようになり、終了しないタイプのProcedureになります。今回作ったProcedure Treeにはこの設定が適しています。
最後に各項目を見やすいように並び替え、初期値を設定します。
項目の並べ替えは欄の右上にある「≪」と「≫」のボタンで。
できたらOKボタンを押してPackageを確定します。完成。
デフォルトのPackage Templateに「Patrol」というのがありますが、今回作ったTemplateは「Patrol」の亜種のように扱うことができます。
【動作確認】
作ったPackage Templateを早速試してみましょう。
こちらはホワイトランの物乞いブレナインのAI Packageです。
街中をパトロールする行動。これを自作のTemplateで作り変えます。
Package Templeteから自作Templateを選択。
彼のスケジュールを、
パトロールしながら「自分の周囲512unit」の範囲で「食べ物」を探し、必要であれば「盗みを許可」した上で見つけた食べ物を「1つ」取る
……ように設定しました。
"Search Loc"は必ずNear Selfのままで、いじるのはRadiusだけにしてください。"Target Criteria"の設定は画像を参考にしてください。
ゲーム内で確認します。
編集したPackageは、彼のAI Packageデータ内では一番下にあります。月曜日以外の9時から14時まで、このPackageが実行されているようです。
ブレナインの近くに、所持品からエールを落としてみました。
AI Packageが正常に動いていれば、すぐに反応して拾います。プレイヤーの所持品はゲーム内では所有権なしと扱われているので、人目もはばからず普通に拾うかと思います。
盗みを許可している場合他人の所有物を拾うときはこのように、人目もはばからず隠密姿勢をとります。
残念ながらNPCの盗みに対して、衛兵は無反応。他のNPC達も無反応でした。
ちなみにこのAI Packageですと、カルロッタの屋台を空にするまで彼は中腰のまま盗みを繰り返し続けるでしょう。下手をすると、屋台下に隠されている彼女の商売用宝箱にも手を出すかもしれません。宝箱は比較的浅い位置に隠されているのに対し、検索範囲は512unit(
1 unit = 1.428 cm)、約7メートルと結構広いので。
さらに問題を挙げるなら"Procedure: Acquire"は、アイテムを取得するまで終了できないという性質があります。壁に飾ってあるアイテムを取ろうとして手が届かず(アクティベート可能範囲に入れず)、なんとかして近づこうと延々壁に向かって歩き続けるなんてこともあります。こうなるとAIPackageのスケジュールが切り替わるまでずっとそのままになることも。
こういった行動を改善するのも、Procedure Tree次第です。Procedure Treeを作ること自体は簡単ですが、きちんと動くものにするには、各BranchやProcedureの性質を把握することが重要になってきます。既存のPackage Templeteは、それらを学ぶ上でとても良いお手本になります。
■サンプルファイル
ダウンロード
今回作成したespファイルです。必要環境は特にありません。ブレナインのスケジュールを編集するModがない状況でお試しください。
作成したAI Packageの名前は「AcquireItemWithPatrolTemplate」です。