コントローラー派にとってはボタンひとつも無駄にできないので、如何に役割を集約させるかが大切になってきます。
立ち止まっている状態からスプリントをすることはなく、走っている状態からスニークに移行することもほとんどありません。このようにスプリントとスニークは相反する機能なので、ひとつにまとめてしまうと便利です。
Papyrusスクリプト
MyTweak.espというプラグインを作り、好きな名前でQuestを作ります。
以下のコードをQuestに割り当てます。
スニークとスプリントを兼用する (papyrus)
Scriptname MyTweak:QuestMainScript extends Quest
Actor Property PlayerRef Auto
Function DoSneak()
if PlayerRef.GetAnimationVariableFloat("Speed") < 150.0
PlayerRef.StartSneaking()
endif
EndFunction
FO4Editを使って、このQuestのForm IDを0x000800にして、ESLフラグを追加してESPFE形式にしておきます。
補足
スプリントキーを押した時に何が起こるかですが、まずゲームエンジンでスプリント処理が行われます。これはとても速いです。
スプリントはプレイヤーがある程度の速さで動いていないと何も起こりません。
ある程度の速さで動いている場合は、既にスニーク中の場合はスニークを解除します。移動方向に関係なく解除します。
そして、ある程度の速さで、かつ前方に移動している場合のみ、スプリントモーションを開始します。
この後、かなり遅れてスクリプトが発動します。内部でFO4SEのホットキー処理が行われているのと、そもそもスクリプトは動作開始までが遅いので、スクリプトが動き出す頃にはすでにスプリントが始まっていたり、スニークが解除済みだったりします。
このせいで、スクリプト内でスニーク中かどうかを判定することができません。仕方がないので、プレイヤーの移動速度をアニメーション変数から読み取り、走ってなさそうならスニークを発動(解除)するという処理をしています。
後方に全速力で下がりつつスプリントキーを押した時は、スニークの切り替えをしたいはずです。なので、スニークしていないならスニークを開始、スニーク中ならスニークを解除としたいところですが、ゲームエンジンによってスニークが解除されてからスクリプトに処理がまわってくるせいで、スニーク中にスプリントを押すと、一瞬スニークを解除してすぐさまスニークを再開するという、おかしな動作になってしまいます。
ホットキーの割り当て
SkyrimではQuestを作り、ReferenceAliasを作り、RegisterForKeyでキーを割り当て、OnKeyDownでキーが押されたことを検知していました。さらにホットキーを自由に設定できるようにするためにはMCMへの登録用Questを作り、スクリプトでMCMの画面を作り込む必要がありました。
Fallout 4ではMCMの設計がかなり異なっており、MCMへの登録はJSONファイルを置くだけでよくなりました。ホットキーはMCMで一元管理できるようになっていて、使い勝手がとてもよくなりました。ホットキーが押された時の動作を自由に設定できて、ホットキーの管理をMCMに任せられるので、Mod側はQuestを作るだけでよくなりました。
MCMに画面を登録
MCMへの登録用JSONは、以下の場所に配置します。
DATA\MCM\Config\Mod名\config.json
config.json (papyrus)
{
"modName": "MyTweak",
"displayName": "MyTweak",
"minMcmVersion": 1,
"pluginRequirements": ["MyTweak.esp"],
"content":
[
{
"id": "mytweak_sprintkey",
"text": "スプリント/スニーク",
"type": "hotkey",
"help": "スプリント/スニークするキーを設定します。",
"valueOptions": {
"allowModifierKeys": true
}
}
]
}
ポイントはidです。
MCMにホットキーを登録
ホットキーの登録用JSONは、以下の場所に配置します。
DATA\MCM\Config\Mod名\keybinds.json
keybinds.json (papyrus)
{
"modName": "MyTweak",
"keybinds": [
{
"id": "mytweak_sprintkey",
"desc": "スプリント/スニークキー",
"action":
{
"type": "CallFunction",
"form": "MyTweak.esp|800",
"function": "DoSneak"
}
}
]
}
idを画面と合わせておきます。