2012/11/26

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

前記事の(1)の続きです。
前回はヒーラーのエイリアスと、AIパッケージを作って、それをヒーリングシーンとしてお膳立てしてやるところまで、やりました。
次はそのヒーリングシーンを呼び出すための仕組みを作りたいと思います。

動作確認を兼ねて、ドール城にカチコミにいきました。喧嘩上等ォ。

ドール城よりもブルーパレスの方が手ごわかった。不死属性の首長たちがてんこもりで。


【手順4】 対象を監視するモニタリングクエストを用意する

ヒーラーに対象となるキャラを回復させるためには、ヒーリングさせたいタイミングで、ヒーリングシーンをスタートさせてやる必要があります。
ヒーリングさせたいタイミング、とは、前回もちらっと触れましたが、対象(今回はプレイヤー)の体力値がある程度減った時です。
対象の体力値を取得すること自体は簡単なのですが、これは常時、ヒーラーがゲーム上で稼動している間、ずっと取得しつづけるような仕組みにしないといけません。
つまり、対象の体力値を取得し、一定値以下に減っていればヒーリングシーンをスタート、そうでなければ何もしない……という処理を一定の間隔で行う必要があります。

対象の体力値を一定間隔でモニタリングする仕組みを作るために、まずは専用のモニタリングクエストを用意します。

モニタリングクエストは、「Start Game Enabled」にチェックを入れないでください。
このクエストは、ヒーラーを雇用したタイミングで開始し、解雇したら終了させます。
また、ヒーラーが雇用されるたびに何度でもこのクエストのステージが使えるように、「Allow repeated stages」にチェックを入れておきましょう。
優先順位の「Priority」は0でかまいません。
このクエストは、役者も小道具も何も無い、裏方に徹したサポート用のクエストですので。

クエストを作成したら、一度設定画面を閉じてesp自体を保存してください。
クエストのオブジェクトは一度「保存」を挟まないと、設定できない箇所が多くあります。
保存が済んだら、再びクエストを開いて「Scripts」のタブを押します。
ここに新規スクリプトとして、モニタリングするスクリプトを追加してやります。

すみません。激しい色使いで。このくらいカラフルじゃないと、おばちゃん見づらいんです…

えーと、スクリプトについては、スクリプト内のコメント以上に詳しく説明する箇所は無いのですが……まあ、いつもこれだけ詳しくコメントつけてるのに、しばらく経つと自分でも何をしていたのかわかんなくなるんですよねえ……
とりあえず、簡単に要点をまとめてみますと。

まず、ゲーム内で一定の間隔で一連の処理をさせるために、「RegisterForSingleUpdate()」という命令を使っています。
この命令は、カッコ内で指定した数値のタイミング後に「OnUpdate」以下のイベントの処理を行ってくれるという……あらかじめ用意した処理を予約しておくための命令です。
SingleUpdateなので、一回こっきりの予約なのですが、予約した処理の中に、再び次回予約の「RegisterForSingleUpdate()」を入れていますので、最初の一回を起動しさえすれば、後は半永久的に処理し続けてくれます。

その最初の一回目……初回起動の命令が、「スクリプトの起動」というところで記述している「Setup()」という自作関数です。
この関数を呼べば最初の一回目の処理が始まります。
あとは、「event OnUpdate()」以下で、ヒーリング対象の体力をチェックする処理を用意しておくわけですが、大事なのは、ヒーリングシーンの最中はモニタリング処理をカットする、という点です。
前回も触れましたが、ヒーリング中の場合は処理をしない、という分岐を挟まないと、対象の体力値が減っている限り、このモニタリングスクリプトはヒーリングシーンを開始する命令をえんえんと出し続けてしまいます。
ヒーリングシーンは非常に繊細な処理ですから、シーンの最中はできるだけ邪魔しないようにそっとしておいてあげてください。

上記のスクリプトでは、プレイヤーの体力が8割を切っていたら、ヒーリングシーンをスタートさせることにしています。
ヒーリングシーンがスタートすると、前回作成したように、Phase1の開始時にHealingnowのフラグがオンになりますので、そのフラグがオンの場合は、何もしないように処理を回避しています。
ヒーリングシーンのPhase3が完了したら、Healingnowのフラグがオフになりますので、そうしたらまたこのモニタリングスクリプトは、対象の体力値をチェックしはじめます。
スクリプトの仕組みとしては、そんな感じです。

ちなみに……このモニタリングスクリプトでは、フォロワー全員のAIをセラーナちゃん式のAIパッケージに切り替えるためのモニタリング処理も一緒に行わせる寸法でいます。
(…というか、もう搭載しちゃいました☆セラーナちゃんみたいなフォロワーが3人もいると非常にカオスです)
こういう、常時駆動型のスクリプトって、処理が重たくなりそうなので、いくつも付けるのはイヤなんですよね。
フォロワー全員にセラーナAIをつけるためと、ヒーラーのために、わざわざモニタリングスクリプトを別々に用意するのはもったいないと思ったので、一緒のModに統合してしまうことにしました。
そのため、今回は、ゲームのデフォルトのフォロワーシステムである「DialogueFollower」を直接改造するという暴挙に出ています。
単にヒーラーを作りたい、というだけならば、新規のフォロワーシステムを作って、そこにヒーラーの機能を搭載するのが、はるかに安全ですので、そちらをおすすめします。


さて、スクリプトを設置し終えたら、次はそのスクリプトを起動するための準備をします。
……おっと、その前に大事なことを忘れていました。
作成したモニタリングスクリプトのプロパティを、忘れずに指定してあげてください。
このスクリプトで使っているプロパティは3つ……整数型のプロパティの「UpdateInterval」とScene型のプロパティの「HealingScene」と、クエスト拡張Script型のプロパティの「DialogueFollower」です。
UpdateInterval」はRegisterForSingleUpdate()を行う、モニタリングの間隔の数値として用意した値です。おばちゃんは「1」を設定しています。
HealingScene」は、【手順3】で用意したヒーリングシーンを指定してください。
そして最後の「DialogueFollower」は……これは、ヒーリング中かどうかのフラグをプロパティとして設定したスクリプトのクエストを指定します。
おばちゃんは「DialogueFollower」クエストの「DialogueFollowerScript」スクリプトの中にフラグを追加したので、上記のような指定になっていますが、別のクエストの別のスクリプトの中に用意した場合は、それに合わせて変えてくださいね。

プロパティの設定が済んだら、次はスクリプトを起動させるために、クエストのステージを準備しましょう。
「Quest Stages」のタブに移って、ステージ0を作成してください。


ステージ0は、念のため「Start Up Stage」にチェックを入れておいてください。
「Start Up Stage」にチェックの入っているステージが、クエストが開始された時に最初に適用されるステージになります。
チェックを入れたら「Log Entry」の欄で右クリック→Newを押して、空のエントリーを挿入します。
本来はここに、ストーリー性のあるようなクエストでしたら、クエストの概略の文章を入れたりするんですけどね。
このクエストは、決してプレイヤーの目からは見えない裏方のクエストなので、そういう余計な説明は要りません。
重要なのは「Papyrus Fragment」という欄に追加するスクリプトです。


「kmyQuest」って何の略字なのかわかりませんが……まあ、それは置いておいて。
「kmyQuest」には、先程設置したモニタリングスクリプトを選択します。
そしてスクリプト記入欄に、「(kmyQuest as oba_UFS_MonitoringScript).Setup()」という一行を記述します。
(※スクリプトの名称などはご自分の環境に合わせて適宜、変更してくださいね)
これは先程のモニタリングスクリプトの中で用意した、初回セットアップの関数を呼び出すための記述です。
つまり、このクエストが始まってステージ0になった瞬間に、モニタリングスクリプトが起動して、モニタリングが始まるようにするのです。
これで、このクエストを開始すればモニタリング処理が始まり、このクエストを終了させればモニタリング処理そのものが消える……という仕組みが出来上がりました。
以上、これでモニタリングクエストは完成です。


【手順5】 ヒーラーのActorを用意する

さて、いろいろ準備が整ってきましたが……あともう一つだけ、予め準備しておかなきゃならないものがあります。
それは、ヒーラーになるためのキャラクター(Actor)です。
残念なことに、ヒーラーには誰でもなれるわけではないんですよね。
少なくとも、おばちゃんの作ったこのヒーラーModの仕様ですと、確実にヒーリング行為を行うためには、ちゃんとセッティングされたキャラじゃないとうまく動いてくれませんでした。

ヒーラーのActorの設定として、必要不可欠なセッティングは、以下の3つです。

(1) Actorのステータスの「クラス」
(2) Actorの取得している「スペル」
(3) Actorの所持している「近接武器」の有無

ちなみにおばちゃんは、ヘイムスカー氏のActorを複製したものでしか試していないので、もしかしたら別種族だったらまた違うセッティングが必要なのかもしれません。
あくまで、ノルド男性ならこんな感じ、という参考までにごらんください。

(1)のクラスについては、これは「CombatMageElemental」というクラスが最適でした。
もちろん全部のクラスを試したわけではないので、もっと他に適したクラスがあるかもしれないのですが……ただ一つだけ言えることは、魔法をガンガン使えるタイプのクラスじゃないと、ヒーリング行為を行うことは難しい、ということです。

クラスの設定欄はActorの「Stats」のタブの下の方にあります。

最初はヒーラーは回復呪文さえ使えればいいんじゃない?と思っていたのですが、少なくともヘイムスカー氏の元のクラスの「Priest(プリースト)」のままでは、うまく動いてくれませんでした。
これは、おばちゃんがいろいろ観察してて思っただけなんですが……回復魔法のスキルの有無より、破壊魔法や変性魔法といった実戦で使える魔法のスキルを数多く持っているということが、ポイントのような気がするんです。

なぜかと言いますと……戦闘中の動作ってホント、システム側からの干渉がありすぎて、CKでは全くどうにもならないんですよ。
たとえば、誰でも心当たりがあるんじゃないかと思いますが、敵に遭遇した時、リディアさんみたいなマッチョなフォロワーにはもっと前方に壁として突っ込んでいって欲しいのに、後ろの方でちまちま弓を打っていて、全然前に出てきてくれない、ということがあります。
(その逆も多いですが……)
あれはたぶん、敵との距離が一定の間隔以上だと弓で攻撃する、という決まりがあるんだと思うのです。
敵の所まで走っていって殴った方が絶対に早いし強いのに、一定以上の距離があると、絶対に弓を取り出します。
そういったシステムから直接操作される現象は、何も弓だけではありません。
キャラの一定距離以内に敵が入ってくると、キャラは反射的に近接武器を構えます。
それは「システムからの神の声」のようなものです。
だから、ヒーリングシーンの真っ最中の、かめはめ波みたいな大げさなモーションを取ろうとしている最中でも、容赦なく割り込んできたりします。
もうこの干渉は、どうやっても止まりません。
プレイヤーのチームメイトをやめて戦線離脱するしかないです。

…で、何故、魔法をガンガン使うタイプがヒーラーに適してるか、というと。
魔法って、武器を構えるよりはるかにモーションが早いし、立ち直りが早いからです。
デュアルキャストは時間がかかっちゃいますが、ファイアボルトとかは片手をあげるだけで済みますし、オークフレッシュみたいな防御魔法などは一瞬シャキーンと光るだけです。
武器の方は、ただ構えるだけでも時間がかかるのに、さらになんか武者震いするようなモーションしたりとか、余計な動作がものすごく多い気がするんですよね。
そのせいで、ヒーリングするためのAIパッケージの動作になかなか移れないのです。
だから、ヒーラーにはできるだけ武器はつかわせないことがポイントです。
破壊魔法やフレッシュ系の防御魔法といった、立ち直りの早い魔法をガンガンつかわせてできるだけ無駄なモーションを行わせないようにするんです。
まあ、このセッティングのおかげで、ヒーラーというより、魔術師として活躍する方が目だってしまうんですけどね。


次に重要なセッティングは(2)のActorが取得している「スペル」です。
これはまず、「Healing」を取得していないと回復を行ってくれません。必須です。


いちおう、「Healing」さえ取得していれば、戦闘中でもヒーリングしてくれるのは確認しましたが、前述したように魔法をできるだけ数多く使わせるために、手間のかからない魔法のスペルをできるだけ数多くぶち込んでやった方が、ヒーリングの成功率が上がります。
Perkは無しでもかまいません。
おばちゃんは回復魔法の効果を上げるために付けてやってますが。

それから次に大事なのは(3)の「近接武器」の有無です。
これも理由は前述した通りです。近接武器を持っていると、ムダにぶんぶん振り回そうとするので、Actorのインベントリから取りのぞいてください。


ちなみにヒーラーのエイリアスの方で、弓を持たせる設定をしておらず、キャラクターが何も武器を持っていない丸腰の状態になると、戦闘に参加しなくなってしまいますのでご注意くださいね。
本当は弓も取り上げたいのですが、丸腰にはさせられないので、仕方なく持たせてやってるんです。
でもまあ、遠距離で使える魔法を取得していると、弓を背中から取り出して構えた瞬間に、「あ、俺には魔法があったんだ!」ということを思い出すのか、弓をしまってくれます。
最初から魔法使ってよ!と思いますが、そのくらいのモーションは大目に見てあげるしかないです。

以上で、ヒーラー用のActorの設定は終了です。
しつこいですが、この辺の調整は、たまたまおばちゃんの環境でうまくいってる…というだけかもしれませんので、あくまで参考程度にお考えください。



記事としては、いちおうこの辺りまでが、「ヒーラーの作り方」ということになります。
あとは【手順3】で用意したモニタリングクエストを、ヒーラーをフォロワーとして雇用する時に開始させてやるだけです。
ヒーラーのエイリアスをフォロワーとして働かせるためには、ヒーラー用のフォロワーシステムを作らなきゃなりませんが、それはヒーラーの作り方というより、フォロワーシステムの作り方になってしまうからなあ……どの程度、突っ込むべきなのか、悩みます。

ひとまず、長くなったので終わります。
続きはまたの機会に。

おまけ。ワンコになつかれてるレイロフ君。

フロドナー君をフォローするように設定してるのに……どうしてここに。
それにしてもヘイムスカー氏がやかましいです。真夜中なのに……大迷惑。

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

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
きみはペット ~アニマルフォロワーのしつけ方~

2012/11/18

二人目の養子~Hearthfireの孤児院送還システム

先日、解析したHearthfireの孤児認定の仕組みを検証するため、申し訳無いと思いつつも子供たちの保護者達をkillしまくって、残された遺児たちが本当に孤児化するのか確かめてみました。
収容人数MAX、大盛況のオナーホール孤児院。

前記事の「養子候補の子供たち~Hearthfireの孤児フラグ」で取り上げた14人の子供たちは、LinkRefに登録されたLinkCustom01~LinkCustom04の関係者が全員死ぬか、もしくはいなくなるかすると、養子縁組可能な子供達のファクションの「BYOHRelationshipAdoptableFaction」に自動的に入会します。
また、死んだのは父親か、母親か、あるいは両方か、という状況のバリエーションによってユーザー定義のActorValueである「Variable06」に所定の数値がセットされます。
これは、プレイヤーが「どうかしたのか?」と尋ねる際の会話のやりとりで、子供が自分の状況を説明するために必要となるフラグです。

「Variable06」が「1」……両親が死んでいる場合の返答が発生
「Variable06」が「2」……パパが死んでいる場合の返答が発生
「Variable06」が「3」……ママが死んでいる場合の返答が発生

そして、この14人の子供たちはそれぞれ、「BYOHRelationshipAdoptableFaction」に入会したというフラグが立った時点で、孤児院送りの処理の中に組み込まれます。
(プレイヤーが子供と同じセル内にいる場合、またはオナーホール孤児院にプレイヤーがいる場合は処理されません。別のセルに移動した後、次の孤児化チェックの処理が始まる際に、孤児院に転送されます)

14人の子供たちのうち、1人でも孤児化して孤児院送りが処理されると、オナーホール孤児院の内装が変化し、新たな孤児のためのベッドが7つ追加されます。
(子供たちが思い思いにくつろいだりするマーカーなども設置されます)

隣の大きい部屋はスカスカなのに、なぜか元院長の部屋に無理矢理7つものベッドが。

新院長のコンスタンス・ミシェルもちょっと、子供の扱いに問題がありそうです。

ちなみにベッドが7つ追加されることから分かるように、新規孤児院メンバーの枠は全部で7人まで、となります。
また、この孤児院送還のシステムは、プレイヤーにすでに二人の養子がいる場合は処理されません
各街に追加されたHearthfireの孤児たちや、元々孤児院にいた4名の子供たちを、早々に二人養子にしてしまっていると、オナーホール孤児院の新規改装オープンは見る機会がなさそうですね。

膝を抱えたり、寝転んだりして、狭苦しいベッドの隙間でくつろぐ子供達。

それから、オナーホール孤児院のコンスタンス・ミシェルが死んでしまっていると、孤児になっても孤児院に転送されることはなく、孤児院の改装も行われないようです。
遺児が孤児院送りにならなかった場合は、元いた場所で、養子縁組のお声がかかるのを待っていますので、養子の枠に余裕があるのでしたら、ぜひ家族にしてあげましょう。

しかし、この一連の孤児化&養子縁組の処理を見ていて思ったんですが……養子のエイリアス枠を増やすのは、思ったよりも難しそうです。
あまりにもいろんなクエストとスクリプトに処理が絡みすぎていて、ちょっと弄るとどこに支障が出るか皆目見当がつかない……
ただ単に、一緒に住む家族の人数を増やしたいのであれば、Hearthfireの養子縁組のシステムを拡張せずに、自分でパッケージを組んでやった方が良さそうです。


…とまあ、そんなわけで、ウルフリック氏の二人目の養子を、孤児院新メンバーの中から決めることにしました。
本当はアレティノ君を養子にしたかったんですけどねえ……(ブツブツ)
アレティノ君も、ボイスタイプを「malechild」にすれば養子にはできるんですけど……あのユニークなボイスじゃないと、他の子とまったく区別がつかなくなっちゃうので、泣く泣く諦めました。

で、どの子にしようかな、と思いまして。
始めは、ウルフリックを助けて処刑されたロッグヴィル氏の恩に報いるために、彼の姪っ子ちゃんを引き取ってもいいかな…とも思ったのですが、うちにはもう娘がいるし、二人目の養子はどうしても男の子が欲しい。
そんなわけで、いろいろ吟味した結果、多少なりとも縁のある、リバーウッドのフロドナー君を引き取らせていただくことにしました。


顔を整形したら、小生意気なクソガキ成分が薄くなってしまいました。

ちなみに、フロドナー君を引き取るにあたって、彼のご両親のジャルデュルさんとホッドさんは殺してません。ちゃんと生きてます。
(検証のテストの際には殺らせてもらいましたが……)
フロドナー君のLinkRefに設定されている、ジャルデュルさんとホッドさんのリンク指定を全部取ってしまうだけで、ちゃんと孤児認定されますので。
まあ、これもある意味、酷い仕打ちといえば酷い仕打ちなんですが……両親が存命なのに、いきなり縁を切られて孤児化するんですもんね。
とりあえず、将来有望な子なので、ぜひ手元に置いて育てたい…とジャルデュルさんにお願いして預からせてもらった、という脳内設定で、罪悪感をごまかすことにしました。

さらに、フロドナー君をうちに迎える際に、彼の忠犬のスタンプも一緒に付いてこられるように、パッケージや所属ファクションを改造しました。
フロドナー君の他に、犬を飼っている子は、マルカルスのエリースちゃんもいますが、どちらもデフォルトでは、犬は新しい環境には着いてこられません。
(エリースちゃんの愛犬はオナーホール孤児院までなら付いてこられるようです)


予定外の処理のためか、犬が沸いた場所がどうやら悪かったみたいで、
テーブルの上に並べていたお膳が引っくり返ってしまいました。
でも怒りませんよ。ワンコのしたことですから……しょうがないよね。


養子になって早々、地下室に降りて剣の稽古を始めるヤル気まんまんのフロドナー君。
乱舞するかのような華麗なダガーさばきに、養父はビックリ仰天です。
おやおや……これは本当に将来有望な逸材かもしれませんね。
少なくとも彼の甲斐性無しの叔父より、優秀なストームクローク兵士になることは間違い無しのようです。

お膳が引っくり返ったままですが、気にしないでください。

子供たちが自発的に食堂のテーブルに着いていたので、ウルフリック氏もつられて着席してみたんですが……
このテーブルってもしかして、椅子が4つ設置されているのは、プレイヤーとその配偶者、そして養子二人、という、『家族』の団欒のためなのかもしれませんね。
ウルフリック氏の隣の空いている椅子を見ていたら、しみじみと、『嫁をもらわなきゃ…』と思えてきました。
ハァ……そろそろ本気で結婚関係クエの解析に取り掛からないとなあ。


そういえば、CKでHearthfireのデータを覗くと、クエストやアイテムなど、Hearthfire関連のオブジェクトにはほとんど、「BYOH」という接頭語がついてるんですよね。
ちなみにDawnguardは「DLC1」です。
Heathfireはなぜ「DLC2」じゃないんだろう……つーか「BYOH」って何の略字なの?
…そう思っていたのですが、UESPのtalkページの中で、同じように疑問に思って質問されていらっしゃる方がいました。
そのディスカッションによると、「BYOH」というのは、

Build Your Own House(home).

…ではないか、とのこと。
なるほどねえ。確かに、自分自身の家を、家庭を作り上げる、それがコンセプトのDLCですものねえ。
メインホールの暖炉の前に、家族のエイリアスを被ったNPC達が集うのを見ていると、制作側がやりたかったこと……複雑な処理の果てに実現させようとしていた「家庭の団欒の雰囲気」、のようなものが、なんとなく伝わってくるような気がしました。
まあ、色々やりすぎて、ポカしちゃってる箇所も多々あるんですけどね。

【関連記事】
養子候補の子供たち~Hearthfireの孤児フラグ
Hearthfire~養子縁組の条件


2012/11/15

養子候補の子供たち~Hearthfireの孤児フラグ

以前、Hearthfireで養子縁組が可能な子供の条件は、「BYOHVoicesAdoptedChildren」というフォームリストに登録されている子供ボイスと、「BYOHRelationshipAdoptableFaction」というファクションの特定のランクにあることが鍵だという記事を書いたのですが、実際にどういう経緯でそのフラグが立つのかまでは、全然わかっていませんでした。

特に、最初から孤児というわけではない、保護者と一緒に暮らしている子供は、いったいどういう状況下になったら養子縁組が可能な孤児のフラグが立つのか……
どうやら、両親や兄弟など、子供を保護している大人が死ねば、必ずしも孤児になるわけではないようで、この子は養子になったけど、この子はダメみたい……みたいなカキコミをたまに見かけるのですよね。
親が死んだら必ず孤児になる、というわけではない、ということは、どこかに「保護者が死んだら、孤児化する子供たち」のリストがあるんじゃなかろうか……
そう思って、探してみたら……やっぱり、ありました。

どうやら、「BYOHRelationshipAdoptable」というクエストの「BYOHRelationshipAdoptableAccessor」というスクリプト……こいつの「OrphanableChildren」というプロパティに登録されたActorのReferenceの配列が保護者が死んだら孤児になる子供たちのリストのようです。

その孤児候補者リストに登録されている子供は、全部で14人。
オナーホール孤児院の子供たちや、Hearthfireで新規追加された孤児を除くと、スカイリムには30人くらいの子供がいますので、約半数が抜擢された、というところでしょうか。
ちなみに、孤児候補者リストに載った子供のReferenceには、LinkCustom01~LinkCustom04のキーワードと共に、保護者のLinkRefが追加されていまして、そのリンクされた関係者が全員死亡すると、孤児化フラグが立つ仕組みになっています。

リバーウッドのアルヴォアさん家の娘、ドルテちゃんのLinkRef。
LinkCustom01が父親、LinkCustom02が母親、03や04はその他の保護者です。


…というわけで、孤児になる可能性のある、14人の子供たちをまとめてみました。
ちなみに、本当に孤児になるのかは、まだ検証はしておりません(オイ)。
週末にでも、孤児院行きの動作確認も含めて検証したいと思ってますが……とりあえず、スクリプトを見る限りでは、この子達が養子候補ですよ、ってことで。
孤児認定の仕組みについては、長くなりそうなので、また改めて書きたいと思います。


フロドナー (リバーウッド出身・ノルド男子)
父・ホッド、母・ジャルデュル の死亡後に孤児化
レイロフの甥っ子。あんなに懐いていたのに、どうやらあの甲斐性無しは、姉夫婦の代わりに保護者になってやるつもりはまったく無いらしい。
「僕を怒らせたら、嫌がらせをしてやるからな!」
グラルナハ (リフト出身・ノルド男子)
母・グロスタ の死亡後に孤児化
リフテン近くのハートウッド工場に、母親と二人で暮らす少年。父・リーフナーは一攫千金を夢見て家を出て行ったが……
「やっぱり!父さんはヒーローだったんだ!」
ナッド (ソリチュード出身・ノルド男子)
父・スニリング、母・カトラ の死亡後に孤児化
ソリチュードのカトラ農場の跡取り息子。あの農場ってドラゴン遭遇率、結構高いから……その救済処置なんですかねえ。
「父さんが、僕には読む才能がないって言うんだ。でもママはそんな才能は農園で働くのに必要ないってさ」
スクリ (リーチ出身・ノルド男子)
母・エイディス 従業員・レオンティウス の死亡後に孤児化
タイバー・セプティムが滞在したという由緒ある宿屋オールド・フロルダンで、母親と一緒に働く少年。かなりのしっかり者……というか、ませている。
「飲みすぎたら追い出すよ。酔っ払いはお断りだからね」
クリントン (ドラゴンブリッジ出身・ブレトン男子)
父・アザダ、母・ミシェル、姉・ジュリエンヌ の死亡後に孤児化
ドラゴンブリッジのリルヴィエーブ家の息子。勇ましい兵士に憧れる男の子。ラッキーというヤギをペットにしている。
「僕が兵士だったらなあ!旅も夜更かしも遊びも、たくさんできるんだ!」
ドルテ (リバーウッド出身・ノルド女子)
父・アルヴォア、母・シグリッド の死亡後に孤児化
リバーウッドの鍛冶屋の一人娘。目指せ、女エオルンド!
フロドナーとは幼馴染。将来この二人がくっついたら、ハドバルとレイロフは親戚になるのだろうか……
「いつか、自分の剣を作るんだから!」
ブレイス (ホワイトラン出身・レッドガード女子)
父・アムレン、母・サフィール の死亡後に孤児化
ホワイトランの苛めっ子。もっとも苛められるバトル・ボーンの息子にも問題がありすぎだが……
「何を見ているの?怖くないわよ!」
ブリッテ (ロリクステッド出身・ノルド女子)
父・レムキル の死亡後に孤児化
ロリクステッドのレムキルの農場で暮らす少女。双子姉妹のおねえちゃん。
「私の方が5分くらいお姉さんなのよ」
シセル (ロリクステッド出身・ノルド女子)
父・レムキル の死亡後に孤児化
ロリクステッドの双子姉妹の妹ちゃん。どうやら霊感少女っぽい。
「良いドラゴンの夢を見たの…」
エイリッド (ウィンターホールド出身・ノルド女子)
父・ダグール、母・ハラン の死亡後に孤児化
ウィンターホールドの宿屋「フローズンハース」の娘。ウィンターホールド首長の息子アッシュールと仲良し。
「アッシュールのパパは大学のせいで悪いことが起きたって言ってるそうよ。でも魔術師はかっこよかったな」
レフナ (ダークウォーター・クロッシング出身・ノルド女子)
母・トルミール 母の同僚(?)・ソンダス の死亡後に孤児化
ダークウォーター・クロッシングのゴールデンロック鉱山で母と暮らす少女。父親は死んでるわけではない様子だが、あまり当てにならない男らしい。
「デルキーサスは川の深くまで潜りによく連れて行ってくれたわ。会えなくてさみしいな」
ミネット・ビニウス (ソリチュード出身・ノルド女子)
父・コルプルス・ビニウス の死亡後に孤児化
ソリチュードの宿屋「ウィンキング・スキーヴァー」の娘。兄貴にソレックス・ビニウスがいる筈なのだが……なぜか孤児化する。
「パパはもうロックヴィルには会えないって言うけど、理由は教えてくれないの」
スヴァリ (ソリチュード出身・ノルド女子)
父・アドヴァル、母・グレタ の死亡後に孤児化
ソリチュードで公開処刑されたロッグヴィルの姪にあたる女の子。
「ママはロッグヴィル叔父さんが死んでからあまり話さないの」
エリース (マルカルス出身・ブレトン女子)
母・ダイグレ の死亡後に孤児化
マルカルスの街の側にあるレフト・ハンド鉱山で働く労働者の娘。
「どうしてレフト・ハンド鉱山って呼ばれてるの?鉱山労働者は右手を使ってもいいの?」

【関連記事】
二人目の養子~Hearthfireの孤児院送還システム
Hearthfire~養子縁組の条件