2012/11/25

ヒーラーフォロワーの作り方(1)

以前、中途半端に作ったっきり、放置プレイ中だったヒーラーのフォロワー・ヘイムスカー氏を、再び作り直してみました。
すでに作り方をすっかり忘れてしまっていたので、再現するのはホント苦労しましたよ…。
…というかですね、以前作った時は、たまたま色んな偶然が重なってうまく動作してたというだけだった、ということが判りました。
やっぱり、ブログの記事などにして、きちんと要点を整理しておかないとダメですね。

動作確認を兼ねて、ドラゴンズリーチにカチコミに行きました。

ここ、不死属性が五人もいるなんて……そんなの聞いてない。

かなり力技で動かしている、非常に危ういバランスの上に成り立っている仕組みなので、レシピとして紹介するのはためらわれる不完全な出来なのですが、何より忘れっぽい自分のために、また一から検証し直すことにならないように、Mod作成の手がかりとなる記録を残しておきたいと思います。
ちなみに記事の通りに作成したとしても、ちょっとした設定の違いやセーブデータの状態、他のModの干渉などで、動作しないことが多々あると思いますので、あくまで参考程度にごらん下さいね。


さて、まずはヒーラータイプのフォロワーを、どうやって作るか、ということなんですが。
今までデフォルトのゲーム上で、戦闘中に仲間が危なくなったら回復魔法をかけてくれる…というような、心優しいキャラを見たことがありますか?
おばちゃんの知る限り、他のNPCに回復魔法を使っているシーンを目撃したことのあるキャラは、ホワイトランのキナレス聖堂で怪我人を治療している人くらいです。
あとは大学の回復魔法の先生もたまに練習してたかもしれないなあ……
しかしどちらも戦闘中に仲間を助けるために使う、というのではありません。
単に演出として魔法を使っているだけです。
デフォルトで、戦闘時に自発的に他者回復呪文を使うキャラがいない、いうことは、コンバットスタイルやクラスをカスタマイズしたり、使える魔法をいくら追加してやったりしても、ヒーラーは作れない、ということです(たぶん)。
なので、指定したターゲットに回復呪文を使うAIパッケージを自前で用意し、回復させたい場面でそのパッケージに切り替える、というヒーリング機能をこしらえることになります。


【手順1】 ヒーラーのエイリアスを作成する

まずは、ヒーラー専用のエイリアス枠を作ってやります。
おばちゃんは今回、デフォルトのフォロワーの基幹システムである「DialogueFollower」クエストにダイレクトにエイリアスを追加してしまいましたが、新規で専用のクエストを作成するのでも構いません。
いや、むしろ、新規で独立したヒーラーフォロワーシステムとして作成できるのなら、そっちの方がいいかも……デフォルトのフォロワーシステムは、正規のクエストラインにからんでくる重要なオブジェクトなので、ヘタに弄るとゲームの進行が妨害されたりしますのでね。

「DialogueFollower」に「Healer」というエイリアスを追加します。

設定は「Follower」エイリアスをそっくり真似て作ります。

基本的に「DialogueFollower」の「Follower」エイリアスの設定のままでいいのですが、赤枠の部分、「Combat Override Package List」の部分だけは何も選択しない「NONE」状態にしなくてはなりません。
そうしないと、戦闘時にこのAIパッケージが優先されるので、ヒーラーがまったく言うことを聞いてくれなくなります。
あとはスクリプト欄ですが、ここにはヒーラーが死んだ時の処理や、待ちぼうけをくらっている時の処理などを行うスクリプトをつけます。
デフォルトのフォロワーのエイリアスに付属している「FollowerAliasScript」のままでは当然動きませんので、このヒーラー用に処理を書き換える必要がありますが……スクリプトの改造は、後でまとめて処理しますので、とりあえずエイリアスの作成はここで終わります。


【手順2】 ヒーリングに使うAIパッケージを用意する

次に、他者に回復魔法をかける専用のAIパッケージを作りましょう。
Object Windowの「Package」のカテゴリを選んで、検索窓に「heal」と入力すると、下画像のような回復行動に関連のあるパッケージがピックアップされてきます。


上画像の赤枠の二つが、ホワイントランのキナレス聖堂で怪我人の治療をしている人に使われているAIパッケージです。
別に新規で作成してもいいのですが、魔法を選んだりするのが面倒なので、この既存のパッケージのどちらかを複製(Duplicate)して、他者回復を行うパッケージを作成します。

まずは最初の「Packageタブ」の設定です。

パッケージのオーナークエスト(Owner quest)の指定欄ですが、キナレス聖堂の人のパッケージを複製するとキナレス聖堂のシーンのクエストがあらかじめ入っちゃってますので、その指定を変えてください。
回復を受ける対象があらかじめ決まっている特定のキャラならば、オーナークエストの指定は要りませんが、たとえば他のフォロワーに回復魔法をかけたい、などという場合は、回復魔法の対象をフォロワーのクエストのエイリアスにしなければなりません。
その場合は、その対象のエイリアスが設定されているクエストを、パッケージのオーナーに指定してやる必要があります。
今回はとりあえずプレイヤーを回復するだけのヒーラーを作りたいと思いますので、Owner questには何も指定せず、targetにはプレイヤーのReferenceを直接指定しています。

それからもう一つ、忘れてはならない設定としては、「NumToCastMin」「NumToCastMax」の設定があります。(上画像の赤枠で囲った部分)
これは、このパッケージの再生中に、指定された魔法を、最低何回、最高何回使うか、という使用回数指定の項目です。
ここの設定を、最低(Min)1回、最高(Max)1回という風にしておくと、対象(target)に魔法が一発ヒットした時点で、このパッケージが「終了」となるフラグを出してくれます。
この終了フラグは、目に見えないものですが、非常に大事なシグナルです。
実はここで作った回復魔法のパッケージは、後でクエストのシーン(Scene)の中に組み込んで再生させるつもりなのですが、このパッケージの「終了」フラグが無いと、次のフェイズに移れなくなってしまうのです。
もちろん、回数を増やしても、きちんとその回数分だけ回復魔法を唱えることができるなら支障はないのですが、2回以上に増やすのはあまりおすすめはできません。
どうしてかというと、UseMagicタイプのパッケージは、途中なんらかの割り込みを食らって再生が中断されると、次に再生する時に動作がおかしくなることがあるからです。
ロード画面を挟んだり、キャラに「disable/enable」をかましたりすれば大丈夫なのですが、同じセルに居続けている場合はどういうわけか、魔法を構える動作はするものの、対象に放出することができずに、壊れたCDプレイヤーみたいにカクカク震え出してしまいます。

まあ、たった1回こっきりにしていても、戦闘中はミリ秒単位で割り込みを食らいまくるので、なかなか無事に正常終了できないんですけどね。

お次は「Flags」のタブ。参考までに……

ちなみに「Ignore Combat」に思いっきりチェックを入れていても、プレイヤーのチームメイト化しているだけで戦闘に巻き込まれます。ホント意味無いです。
まあ、できるだけ余計なことしないように、という気休め程度に設定しときましょう。


次は「Begin/End/Change」のタブ。ここに付け加える小細工が非常に重要です。

「Begin/End/Change」のタブでは、パッケージの開始時、終了時、そして他のパッケージに切り替わった時のタイミングで処理される独自のスクリプトを付けることができます。
ここで、「On Begin」のスクリプト欄に「akActor.EnableAI(false)」と「akActor.EnableAI()」のスクリプトを入れてやるのがコツ、というか鍵です。
どうしてこんな処理を入れるか、といいますと。
パッケージの動作主であるキャラ(akActor)のAIが一瞬止まって、再び動き出す…という処理を挟むと、目に見えない何か(?)がリセットされるらしくて、二度目以降の再生や戦闘時の再生に詰まったりすることが、比較的軽減されるからです。
完全に防御する手段ではない、というのが残念ですが……
まあ、予防策というか、おまじない、のようなものですね。

本当は「disable()」「enable()」の方が確実なんですが、でもキャラクターの姿が一瞬消えてしまうのが不自然なので……代わりにキャラのAIの動作をオン・オフする「EnableAI()」を使っています。
この辺のパッケージの挙動を調整するのには、本当に苦労しましたよ。
もうね、パッケージの再生中に攻撃を食らって、体がのけぞってしまっただけで、挙動がおかしくなるんです。
だから敵をModでわんさか沸かせて、無双スタイルで乱戦状態で遊ぶのが好き、という方には、このヒーラーModはほとんど使えません。
回復魔法を使うパッケージを正常に動作させるには、敵になるだけ邪魔されずに、割り込みのモーションをできるだけ食らわない環境で、ヒーリングを行う必要があるからです。
まあ、敵に囲まれてフルボッコにされたとしても、それはそれでいいんですけどね。
膝をつく状態になると、どういうわけかキャラがリセットされてパッケージの再生が復活するので……瀕死になる機会が多いと、ある意味、動作がバグりにくくなります。
もっとも、膝をついている間はヒーリングは行えないので、結局使えないことに変わりはないですが……

ちなみに、この「On Begin」「On End」「On Change」のスクリプト欄に、デバッグ用の目印となるコメントを入れておくと、パッケージがうまく再生されない時にどの辺りで処理が詰まっているのか、問題を見つける手がかりとなります。
回復魔法を使わせるパッケージの制御は、一発でうまくいくことはほとんど無い、といっても過言では無いので、細かくコメントを入れて動作を逐一確認しながらチューニングするのがポイントです。
DLCを導入してからというもの、ログが見づらくってかないませんが、日本語でコメントを入れておくと目立つのでおすすめですよ。

ついでにトラベルタイプのパッケージも作っておきます。

これは必須ではありませんが……プレイヤーの視界にも入らないような遠方にいるのに、いきなり回復呪文をかけられるとわけがわかんないので……回復魔法を使う前には、必ず対象の近くに来させたいと思います。
ただしあんまりプレイヤーの近くまで呼び寄せると、乱戦に巻き込まれる確率があがるので、そんなに近距離を指定しない方がよろしいです。
Flagsタブで「Preferred Speed」の設定を「Run」にするのを忘れずに。
Runにしないと、のんびり歩いてやってきます。


【手順3】ヒーリングシーンを作成する

ヒーラーのエイリアスとパッケージの準備ができたら、今度はヒーリングを行うシーンをヒーラーのエイリアスを作ったクエスト内に作成します。
…と、その前に一つだけ、準備しなくてはならないものがあります。
それは、ヒーリングシーンが行われている最中かどうか、という状況を判別するためのフラグです。

ちなみに、他者に回復呪文をかけるシーンを作ったとして……そのシーンを再生するにはどうしたら良いと思いますか?
ヒーラーには回復呪文をかけて欲しい時だけ、回復シーンを再生して欲しいですよね。
回復呪文をかけて欲しい時、というのはつまり、対象(今回はプレイヤー)の体力が一定値以下に減ってしまっている時です。
体力が減ったら始まる便利なイベントスイッチみたいなものはデフォルトでは存在しないので、対象の体力を常時監視して、一定の数値以下になったらヒーリングシーンがスタートする、という常時駆動型のモニタリングスクリプトを自前で設置する必要があります。
そのモニタリングするスクリプトの中で、ヒーリングシーンが行われている最中かどうかというフラグは必要になってくるんです。
なぜなら、そのフラグがないと、ヒーリングを行ってる最中でも、対象の体力が減っている限り、ヒーリングシ-ンをえんえんと呼び出し続けてしまうからです。
ヒーリングシーン中は処理を止め、シーンが終わったら再びモニタリングする、というようにしなければ動作がおかしなことになってしまいます。

ヒーリングシーンが行われている最中かどうか、というフラグは、クエストの拡張スクリプトの中にプロパティとして設置しておきます。
「DialogueFollower」クエストでしたら、メインスクリプトの「DialogueFollowerScript」の中にでも追加してしまいましょうかね。

「DialogueFollower」クエストのScriptタブ。

この主要スクリプトは今回、大改造しちゃいますよ~。

「DialogueFollowerScript」のProperty設定画面。

「DialogueFollowerScript」を選択して、Propertiesボタンを押したら「Add Property」で新規プロパティを追加します。
プロパティのデータ型はBoolで、初期値はFalse、名前は「Healingnow」にしました。
このフラグとなるプロパティの準備ができたら、ヒーリングシーンの作成に取り掛かります。

「DialogueFollower」のSceneタブ。

Sceneの作成はあまり馴染みがない方が多いかもしれませんが、作るのは意外と簡単です。もちろんオープニングのシーンのような、大人数を巻き込んだ大スペクタルなシーンを作成するのは至難のワザですけどね。
最初は何もシーンが設定されていないと思いますので、左のカラムに、新規でシーンのタイトルを追加してやってから、右側の広い空間でシーンの詳細を組んでいきます。
まずは右クリックで「New Actor」を選択し、このシーンに出演する登場人物を設置します。
今回はヒーラーの一人舞台なので、出演者は「Healer」エイリアスだけです。
あ……当然のように書いてしまいましたが、シーンに出演できるキャラは、同じクエスト内のエイリアスたちだけです。


ちなみにCKでのクエスト(※ゲームをプレイしている時の「クエスト」という単位の概念とは異なります)というのは、おばちゃんはゲーム上に設置された『劇場』のような存在だと勝手に解釈しています。
大人数が出演するゲームの主幹を成すような大劇場クエストもあれば、裏方で演出のみを提供しているような無人の小劇場もあったり……スカイリムというゲームは、無数の劇場で上演されている、いろんな作品の集合体のようなものです。
その大小さまざまな劇場クエストで上演されている演目では、「Quest Aliases」タブに登録された「エイリアス」が、登場人物やお芝居の舞台や小道具となって、さまざまな場面や機能を、ゲーム上に提供しています。
たとえば、Hearthfireの「BYOHRelationshipAdoption」というクエストでは、「Player(プレイヤー)」「Spouse(配偶者)」「Child1(養子1)」「Child1(養子2)」「FamilyPet(ペット)」「FamilyCritter(飼育している生き物)」……といった家族劇を演じるエイリアスが登場人物として設定されています。
このエイリアスに『配役』されたキャラが、ダイアログやシーンという『台本』に従って、特定のアクションを起こしたり、セリフを喋ったりすることで、サザエさん家のようなHearthfireの家族の場面がゲーム内に実現しているわけです。
本来は無関係なキャラたちが、プレイヤーの「家族」としてのエイリアスの仮面をかぶって予め決められた台本に従って『家族ゴッコ』を演じている……と考えると、なにやら薄ら寒い気分もしますが、考えてみればリアルの家族も似たようなものですよね。
旦那は旦那の、妻は妻の、子供は子供のエイリアスをしっかり被って決められた役柄を演じているうちはうまくいきますが、エイリアスが外れて勝手な行動をしはじめると家庭崩壊しちゃいます。


……話がそれました(笑)
ええと、説明はどこまで行ったんでしたっけ?……あ、そうそう、シーンの登場人物として、「Healer」エイリアスを設置したところまで、でしたね。
登場人物を設置したら、今度はシーンのフェイズ(Phase)を設置します。
フェイズというのは、シーンの場面を区分するフレームというか、ターンのようなものです。
Phase1は、Phase1のターン中に設定された各登場人物の動作(パッケージやセリフなど)が終了すると、次のPhase2のフェイズに進みます。
ですから、シーンのフェイズの中に、決して終了しないアクションを組み込んでしまうと、大変なことになります。気をつけましょう。


今回はフェイズを3ターン分、作成しました。
最初のPhase1では、回復対象のプレイヤーの元に駆けつけてくるトラベルタイプのパッケージをセットしています。
次のPhase2が、肝心の他者回復魔法を使うパッケージのターンです。
Phase3には何のアクションも設定していないので、必要ないのかもしれないのですが、Phase2の回復行動がしっかり終了したかどうか確認したいので、予備フェイズとして設置しています。

Phase2では、ヒーリングを行うパッケージの他に「Timer」のアクションを追加して、待ち時間というか、「ため」の時間を作ってやるのがポイントです。
どうして必要なのかはよくわからんのですが、いろいろ検証した結果、最低でも1秒は「ため」の時間を稼がないと、回復魔法を使うシーンがうまく再生されないということが判りました(特に戦闘中)。
たぶん、他者回復呪文の魔法を使う動作……それもデュアルキャストで魔法を放出するモーションは、かなり時間を食うので、その分の「ため」の時間を作ってやらないと、その動作の最中に次の処理を突っ込まれて対応しきれなくなってしまう、という状況になるんじゃないかなあと思ったりしてます。
ちなみにこの設定はPCのスペックによって、変わったりするのかもしれないです。

各フェイズにアクションを設定し終わったら、今度はスクリプトをつけます。
まず「Phase1」と表示されている枠内をダブルクリックしてみてください。
すると、そのフェイズの開始時や終了時といったタイミングにスクリプトなどを追加できる、フェイズの設定画面が開きます。


この設定画面の「Start」タブではこのフェイズが開始されるタイミング、「Compretion」のタブではフェイズが完了したタイミングで処理される動作を設定することができます。
まずはPhase1のStartタブに、ヒーリングシーンの再生中である、というフラグをオンにするスクリプト処理をつけ加えましょう。


さきほどDialogueFollowerScript内にプロパティとして設置した「Healingnow」というフラグをオンにするため、「(GetOwingQuest() as DialogueFollowerScript).Healingnow = true」という一行を記述してやります。
同様にPhase3の「Compretion」のタブにも、フラグをオフにするための処理……「(GetOwingQuest() as DialogueFollowerScript).Healingnow = false」という記述を追加します。
あとは、動作確認のデバッグ用として、各フェイズにコメントを入れておくとよいです。
このようにスクリプトを追加すると、各Phaseの名称の隣に[S]のマークが付きます。


最後にシーン編集枠の上についている「Edit Actor Behavior」を押して、このシーンが再生されている間のキャラクターの振る舞いを設定します。


この「Actor Behavior」の画面では、登場人物が死んだり、戦闘に巻き込まれたり、プレイヤーに話しかけられたりした際に、一時停止するか、シーンそのものを終了するかを設定することができます。
とりあえず戦闘時に一時停止されては元も子もないので、COMBATのチェックはどちらも外しておきます。
まあ、どのみちシーンが中断されなかったとしても、システムから様々な割り込みをくらうので、戦闘時に全く干渉されない、ということは無いんですけどね。
これらの設定が済んだら、とりあえずヒーリングシーンは完成です。


長くなりましたので、続きは別記事にしたいと思います。
続きはこちら→ ヒーラーフォロワーの作り方(2)

初公開。ヘイムスカー氏の素顔。

フード付きのローブを着たくなる気持ちわかりますね。彼、何歳くらいなんだろ……

【関連記事】
フォロワーの仕組み
フォロワー用ボイスタイプ追加Mod
きみはペット ~アニマルフォロワーのしつけ方~

4 件のコメント:

  1. 以前に自分でもヒーラーmodを作ろうとして、そのまま放置した事があったので実際の作成過程はとても参考になります。
    ありがとうございます。

    返信削除
    返信
    1. 参考になるかどうか、極めてあやしい作りですが……
      「おや?」と思うところがありましたら、ぜひツッコミをお願いしたいです。
      今でも、ちょっとでも他のところをいじると、急に動かなくなったりすることがあるんですよね。
      そんな危なっかしい状態で「作り方」なんて言ってしまって大丈夫なんだろうか……と思わないでもないのですが、忘れないうちに書いておきたくて。
      何かの叩き台にでもなれば幸いです。

      削除
  2. 気になっていたヘイムスカーさんのフードの中は…… ( ̄_ ̄|||)
    人間知らなくていい事もあるんですね…。

    返信削除
    返信
    1. 最初は、信仰のためワザと剃ってるのかな、と思ったんですが、後頭部の具合を見たら、ああ、違うな……と(笑)
      でも顔はけっこうカッコイイですよね。ノルドにしてはスリムだし、おうちもあるし、フードさえ取らなければイケ……う〜ん。

      削除