ベルチバードを改造してみた

Mod作成

これまでに調べたことはベルチバード関連で色々調べてみたにてまとめています。

自分の好きなようにしたかったので、改造してみました。

ファストトラベル

サバイバルモードは普段はファストトラベルが禁止されていますが、ベルチバードに乗っている間はファストトラベルが可能です。正確には瞬間移動ではなく、ベルチバードで移動する、という仕組みです。

これが可能になるのは、ベルチバードに isVertibirdFastTravel キーワードがあるかどうかになります。動的に反映されるため、パイロットが在席している時のみファストトラベルを可能にする、ということもできます。

搭乗位置の変更

Actorにキーワードを付与しておくことで、ベルチバードをアクティベートした際にキーワードが参照されて、搭乗アニメーションと搭乗位置が決定されるようです。

キーワード位置備考
p-AttachGunner砲手
p-AttachPilot操縦士、前方左側
p-AttachCopilot副操縦士、前方右側
p-AttachDogmeat砲手の横ドッグミート専用
p-AttachPassenger後部座席
p-AttachSlot1後方左側パワーアーマー
スパーミュータント
p-AttachSlot2後方右側パワーアーマー
スパーミュータント

ベルチバードはActorですが、騎乗可能なActorであり、アクティベートすると家具の扱いになるようです。この時に使われるアニメーションが種族に定義されています。

種族種族レコードキーワード
HumanHumanRaceSubGraphp-AttachGunner、p-AttachPilot、p-AttachCopilot、p-AttachPassenger
PowerArmorPowerArmorRacep-AttachGunner、p-AttachSlot1、p-AttachSlot2
SuperMutantSuperMutantRacep-AttachSlot1、p-AttachSlot2
DogmeatDogmeatRacep-AttachDogmeat

どうやらアクティベートする前の段階でキーワードの選択が完了していないとならないようです。よって搭乗中の位置変更は流石に無理のようです。一度降りてからキーワードを付け替えて再度搭乗し直す必要があります。

複数のActorが同じ搭乗位置に同時に乗り込もうとすると、搭乗位置が狂ったり、同じ場所に重なって乗ってしまうことがあります。イスやベッドでも起こるので、ゲームエンジンの不具合と思われます。キーワードを付与する際に同じ搭乗位置にならないようにする必要があります。

プレイヤーとその他の扱い

非常にややこしいです。

アニメーションは種族とPOVで分かれています。

1人称視点はプレイヤー専用であり、プレイヤー以外は3人称視点のものが使われます。プレイヤーも3人称視点にしている間は3人称視点のものが使われます。

家具ですが、キーワード FurnitureForce1stPerson が付いているとアクティベート時にPOVが強制的に1人称視点になります。ターミナルやパワーアーマー、ベルチバードに付いています。

逆にキーワード FurnitureForce3rdPerson が付いているとPOVが3人称視点になります。作業台などに付いています。

POVの強制はプレイヤー限定です。

ベルチバードには FurnitureForce1stPerson が付いているため、プレイヤーが搭乗する際は1人称視点のアニメーションが必要になります。

これ以外にも家具の使用中にPOVの切り替えを許可するか、などのキーワードがあるようです。

p-AttachSlot1、p-AttachSlot2に人間が搭乗できるようにする

バニラではパワーアーマーとスーパーミュータントの分しか定義されておらず、それも3人称視点のみになるので、人間はSlot1とSlot2には乗れません。人間の分もSubGraphを追加すれば搭乗できるようになります。

問題はhkxファイルをどのようにして用意するかですが、1から作るとなると極めて難しいため、既にあるものをコピーすることになります。ですが、パワーアーマーもスーパーミュータントもスケルトンが人間とは異なり、身体の各部位の位置やスケールが異なるためか、無理やり人間に再生させると手や首が伸びてしまいます。

hkxファイルですが、搭乗開始が EnterFromStand.hkx で、搭乗中は PoseA_Idle1.hkx が、下乗は ExitToStand.hkx が使われるようです。

搭乗や下乗の再生時間はわずかな間ですし、ActorにSnapIntoInteraction関数を使って搭乗させるとアニメーションの再生すらされませんので、パワーアーマーの分をコピーして済ますのが無難だと思います。

問題はもっとも目にすることになる、搭乗中の PoseA_Idle1.hkx になりますが、パワーアーマーやスーパーミュータントの物を使うと手や首が伸びてしまいます。どうやら位置は PoseA_Idle1.hkx では関係ないようなので、人間用の任意の物が使えます。

フォルダ動き
Actors\Character\Animations\Furniture\ReadingNewsPaper\Standing新聞を読む
Actors\Character\Animations\Furniture\WallLean\Neutral\Female後ろの壁にもたれる
Actors\Character\Animations\Furniture\Refugee\Female\RefugeeA
Actors\Character\Animations\Furniture\Refugee\Female\RefugeeB
怖がる
(Refugee: 難民)

プレイヤーですが、どうやら検査の仕組みがハードコーディングされているらしく、乗ることができません。プレイヤーにSlot1のキーワードをつけて乗ろうとすると、パワーアーマーに乗らないと無理という旨の通知が表示されるので、パワーアーマーなら乗れるのかもしれません。

ミニガンの発射速度を変更する

発射のタイミングはhkx内のweaponFireアノテーションになります。よって適当に間引けば減らすことができます。

hkxファイルの編集はhkxpackを使いました。詳しいことはanimation eventsにまとめてあります。

使われるhkxファイルですが、人間であればHumanRaceSubGraphのData #2579になります。

要約すると、以下のようになります。

  • 1人称視点で
  • 家具を使う時に(騎乗可能Actorに騎乗する時に)
  • 家具(騎乗可能Actor)にキーワード isVertibird が付与されており
  • 家具を使う側(騎乗する側)のActorにキーワード p-AttachGunner が付与されているなら
  • Actors\Character_1stPerson\Animations\Furniture\VertibirdMinigunTurret にあるhkxファイルを使い
  • 上記にない場合は Actors\Character_1stPerson\Animations\Minigun にあるhkxファイルを使う

Bihaviourが何なのかよくわかっていませんが、これが本丸であり、どんな時に何というhkxファイルを使うかが定義されているのだと思われます。例えば、立った状態から家具を使う時は EnterFromStand.hkx を使う、オートマチック武器を発射する時は WPNFireAutoReady.hkx を使う、ということが定義されているのだと思います。幸い、Human、PowerArmor、SuperMutantのいずれも同じ WeaponFurnitureBehavior.hkx というBihaviourを使うようになっているようなので、心配は要らなそうです。

よって、プレイヤーがガンナー席に着いて1人称視点でミニガンを発射する時は以下のhkxファイルが使われる、ということになります。

Actors\Character_1stPerson\Animations\Minigun\WPNFireAutoReady.hkx

とりあえずこのファイルを差し替えればアニメーションも変化します。

ですが、これだと常に変わってしまうため、条件次第で切り替えるのであれば、専用のキーワードと専用のフォルダを用意して、差し替えたhkxファイルを専用ファルダに配置して、SubGraphを追加して上記のキーワードとフォルダを指定すればいいことになります。

以下は人間のSubGraphを追加した例です。

パワーアーマーを着て搭乗するのであれば、パワーアーマーの分のSubGraphも必要になります。

条件は搭乗前に設定済みにしておく必要があります。搭乗後は切り替えられないようです。

どういうわけか、この条件を満たしている間は1人称視点でベルチバードに搭乗できなくなります。原因は不明です。ベルチバードから FurnitureForce1stPerson を外し FurnitureForce3rdPerson をつけることで搭乗できるようになります。

ベルチバードが攻撃されないようにする

Unconscious状態にする

ひとつはベルチバード自体に SetUnconscious 関数を使って気絶扱いにすることです。気絶中はすべてのActorから無視されます。

Unconsciousにはいくつか問題があります。

Unconscious中はアクティベートが阻害されます。プレイヤーが常に最初に乗るのであれば、アクティベートを検知してからUnconsciousを解除して、スクリプト内から再度アクティベート処理を実施する必要があります。

UnconsciousはUnloadで解除されるようなので、OnLoadのたびにUnconsciousを設定しなおす必要があります。

気絶中は行動できないため、着陸中のみ使えます。

Factionで制御する

もうひとつはFactionで制御する方法があります。こちらは常に有効です。

囚人用のFactionを設定すると楽だと思ったのですが、攻撃されてしまいます。

機体を制御する

Packageで制御します。

離陸と上空旋回はOrbitテンプレートを使います。

上空で静止させるにはHoverテンプレートを使います。

指定した地点に着陸させるにはTravelパッケージを使います。

戦闘を制御する

通常のActorと同様に戦闘状態になればCompat Packageに切り替わり戦闘行動を始めると思います。

戦闘をさせないのであれば、パッケージにIgnore Combatフラグを付けることで、戦闘状態を無視してパッケージの実行を継続します。

プレイヤーが乗っていると戦闘しないような感じがしました。このあたりはまだ検証中です。

高度を制御する

OrbitパッケージとHoverパッケージにはHeightのパラメーターがあります。これで高度を制御できます。

移動中はOrbitパッケージが適用された状態でなければなりません。

Orbitパッケージは旋回する場所を指定しますが、場所にいない場合は、まずその場所まで移動します。この時の高度にHeightパラメータが適用されるようです。

Travelパッケージは着陸する場所を指定しますが、まずは着陸地点まで移動します。この時の高度は制御できないようです。

Hoverパッケージで高度のみをかえたら浮上したり下降したりさせたいのですが、Hoverそのものを最初からやり直すようで、無駄な動き方をしてしまいます。向きをかえる場合も同様です。

着陸時の向きをかえる

場所は基本的にはマーカーなどのリファンレスを指定することになりますが、Angleが反映されるようです。

空中静止時に向きをかえる

着陸時と同じくリファレンスの向きが反映されるようです。

さらに、SetLookAtでヘッドトラッキングを行うと、その場で向きをかえることができます。

旋回中は効かないようです。

旋回方向を制御する

OrbitパッケージにRotateのパラメーターがあるので、これが関係していそうなのですが、変更しても挙動がいまいちわからず、旋回方向を制御する方法が不明です。

原則として反時計回りに旋回してくれないと、砲手が標的を狙えないので困ります。

急停止する

自分に対してHoverパッケージを使うと即座に停止します。

状態を監視する

飛行状態はベルチバードのGetFlyingStateで確認できます。PapyrusとCondition Functionの両方にあります。

アニメーションイベント

アニメーションイベントを受け取る方法もあるようですが、Actorの3DがLoadされた状態でないと発火しないので注意します。

Spell

Spellを使う方法があります。こちらも3DがLoadされている必要があります。

GetFlyingStateを見て発動するMagic Effectが変化するアビリティ(常時発動型のSpell)を用意します。個々のMagic EffectにはScriptを設定しておき、OnEffectStartイベントに処理を書いておきます。このアビリティをベルチバードに持たせておくことで、FlyingStateが変化するタイミングでScriptを実行できます。

Package

GetFlyingStateを見てベルチバードに適用されるPackageを変化させ、PackageにScriptを設定しておけば、Packageの切り替わりでFlyingStateの変化を検知できます。

Packageの問題は適用速度が遅いので、ベルチバードにEvaluatePackageを実行してお尻を叩くかのごとく適用を促すと、少しはマシになります。

Scriptで回す

効率面では最悪ですが、結局のところこれが確実です。

ファストトラベル中の特殊な状態

注意すべきがファストトラベルです。特殊な実装になっているらしく、Pip-boyでマップマーカーを指定した瞬間に以下の処理が強制的に実行される特殊な状態に遷移するようです。

  • 着陸しているのであれば離陸する
  • マップマーカー周辺まで移動する
  • 着陸可能な地点を検索する
  • 着陸する

おそらくハードコーディングされているSceneを実行するのだと思われます。この特殊な状態にいる間はベルチバードのパッケージが見えない何かに上書きされている状態らしく、スクリプトからも取得できません。また、HUDにLANDINGという操作が表示されることでも、この特殊な状態にいることを判別できます。

特殊な状態にいる間はスクリプトからは制御不能になるため、状態の監視だけに留めるしかないようです。

当初の目的地に到着するか、目的地を再度指定し直すか、あるいはLANDINGを押してそのあたりに着陸させるか、いずれにせよ着陸が完了すると、この特殊な状態から解放されるようです。

着陸した直後に離陸してしまう

パッケージの管理がおかしい場合に起こるようです。特にファストトラベルを実行した場合や、HUDからLANDINGを実行した場合に起こります。

パッケージは通常、条件式を設定しておいて、状況ごとに適用されるパッケージが変化します。着陸することで状況が変化し、離陸するパッケージ(Orbitパッケージ)がすぐさま適用されないようにします。

上で説明しているアビリティで着陸態勢に入ることを検知し、すぐさま離陸してしまわないように準備するのがよいでしょう。

タイトルとURLをコピーしました