Critical Hit – Backstab and Parryを安定させる

Modを作ろう

Backstabが出たり出なかったりするのでなんとかしてみました。

Critical Hit – Backstab and Parryとは

Critical Hit - Backstab and Parry in Skyrim Special Editionで紹介しています。

スクリプトベースなので改造しやすいのと、バックスタブのモーションがバニラのものと同じで好みなので使い続けています。

問題もあって、本来はアニメーションがFNIS用で、もう記憶にないのですがFNIS時代はきちんと動いていたように思います。これがNemesisになってから不発することが多くなりました。

デバッグの結果、PlayIdleWithTarget関数でアニメーションを再生する手前までは問題なく、アニメーションの再生が安定しないようでした。原因は不明ですが、おそらくはActorの状態が適切ではないようで、そのうち直ったり、また不発になったりします。

また、アニメーションは再生されるが攻撃がヒットせず、相手にダメージがまったく無いことがあります。

アニメーションについて調べてみた

そもそもの話として、Skrimにおけるアニメーションの管理や制御はどのように実装されているのか、ということについて調べてみました。

大きく2つに分かれているようです。

Havok担当ゲームエンジン担当
(プラグイン)
BehaviorAction
アニメーション
(hkx)
Idle Animation

Havok担当分

Actorは普段はHavokの制御下にあります。重力の影響を受けて地面に着地しますし、障害物に阻まれると進めなくなります。こういった制御はHavokが実現しているわけです。

BehaviorはHavokにおけるActorのアニメーション周りを制御するための計画表のようなもので、いつどのアニメーションを再生できるか、ということを設定しているようです。

アニメーションはActorのアニメーションそのものです。Actorのスケルトンがどのように動くのかを定義しています。

Havok担当分のデータはhkxというファイルで用意されています。これを編集する手段はベセスダからは用意されていません。

個々のアニメーションはそれ自体で完結しており、世界中のModderによって作成、公開されています。作成にはBlenderや3ds Maxといったモデリングツールを使用します。

Behaviorは個々のアニメーションをまとめる役割をしており、環境ごとに異なります。これをなんとかしてくれるのがFNISやNemesisになります。

ゲームエンジン担当分

現実世界のプレイヤーの入力デバイスから入力を受け取り、それをActionとしてActorに発生させます。

ActionはActorの行動で、ひと通り用意されています。例えば右攻撃はActionRightAttack(Skyrim.esmの0x13005)になります。どういった操作がどのActionに繋がるのかは、ゲームエンジン内部にハードコーディングされていると思われます。ですから編集はできません。

Idle Animationはどういった条件でどのアニメーションを再生するかを決めるものです。Idle Animationには親子関係があり、階層化されています。さらに親としてActionを指定できます。

コントローラーのRTを押すとActionRightAttackというActionが発生し、紐づけられているIdle Animationが精査されて条件に合致したものが再生される、という仕組みのようです。

Idle Animation自体はCKやxEditにて編集可能です。

また、Actionに紐づいていないIdle Animationもあり、CK上ではLooseという扱いになっているようです。スクリプトから指定して再生させることが前提のようです。

アニメーションファイルを調べてみた

このModが追加しているアニメーションはCH_paired_1hmkillmovebackstab.hkxになります。これはどうやらバニラのpaired_1hmkillmovebackstab.hkxに手を加えたもののようです。

このバニラのアニメーションですが、マルカルスに入ったところでウェイリンがマルグレットに仕掛ける攻撃にも使われています。Sceneの中でPlayIdleWithTarget関数を使っており、これが不発になったことはありません。

試しにCritical Hitが再生しているCH_paired_1hmkillmovebackstab.hkxのかわりにpaired_1hmkillmovebackstab.hkxを使うようにしたところ、発動率が上がったように思います。ただし、相手が確定で死亡するようです。

hkanno64で両者を調べてみたのですが、アノテーションが一切なく、どういう処理になっているのかわかりませんでした。おそらくはアノテーション以外にもTriggerと呼ばれる命令の仕組みがあるようです。

OARにはTriggerを無視するというオプションがあるので、OARで置き換えてオプションを設定してみたところ、死ななくなりました。ただ、効果音もなく、イベントも発火しなくなってしまいます。

FNIS用設定ファイルを参考にアノテーションを追加してみました。

# numOriginalFrames: 97
# duration: 3.200000
# numAnnotationTracks: 201
# numAnnotations: 18
0.000000 2_KillMoveStart
0.005000 NPCKillMoveStart
0.036000 NPCSoundPlay.NPCKillStruggle
0.240000 NPCFootScuffLeft
0.772000 NPCFootScuffRight
0.916000 NPCFootScuffLeft
1.105000 NPCweaponSwing
1.118000 NPCSoundPlay.NPCKillStabIn
1.202000 NPCHitFrame
1.328000 NPCSoundPlay.NPCKillGore
1.535000 NPCSoundPlay.NPCKillStruggle
1.867000 NPCSoundPlay.NPCKillStabOut
2.202000 2_KillMoveEnd
2.849000 NPCFootScuffLeft
3.003000 NPCFootScuffRight
3.164000 NPCpairedStop
3.166667 NPCPairEnd
3.166667 NPCKillMoveEnd

結局のところ、最後には死んでしまいます。

強引に死亡しないようにしてみた

対象にStartDeferredKill関数を実行して不死化しておくと死ななくなるので、用が済んだらEndDeferredKill関数で不死化を解除します。

でも、EndDeferredKill関数を実行した直後に死んでしまいます。これはアニメーション中のKill命令自体は止まっておらず、関数名のとおり死を遅延させているだけだからのようです。

そこで、アノテーションを部分的に取り除いてみたりしたのですが、ダメでした。どうやら、KillMoveStartではじまり、KillMoveEndで終わると、相手はかならず死ぬようです。この2つだけを取り除いてみたところ、死ななくなりました。

スクリプト側はこのイベントをみて処理を入れているため、かわりとなるイベントが必要です。

Behavior Data Injectorを使ってイベントを新規追加

SKSE\Plugins\BehaviorDataInjector\CriticalHit_BDI.jsonになります。

[   
    {
        "projectPath": "Actors",
        "type": "kEvent",
        "name": "BackstabStart"     
    },
    {
        "projectPath": "Actors",
        "type": "kEvent",
        "name": "BackstabEnd"     
    }
]

アノテーションを更新

pairedアニメーションの場合、そのまま書いてもダメなようで、頭にNPCをつけると攻撃側、2_をつけると被害者側にイベントが発生するようです。

# numOriginalFrames: 97
# duration: 3.200000
# numAnnotationTracks: 201
# numAnnotations: 16
0.000000 2_BackstabStart
0.036000 NPCSoundPlay.NPCKillStruggle
0.240000 NPCFootScuffLeft
0.772000 NPCFootScuffRight
0.916000 NPCFootScuffLeft
1.105000 NPCweaponSwing
1.118000 NPCSoundPlay.NPCKillStabIn
1.202000 NPCHitFrame
1.328000 NPCSoundPlay.NPCKillGore
1.535000 NPCSoundPlay.NPCKillStruggle
1.867000 NPCSoundPlay.NPCKillStabOut
2.202000 2_BackstabEnd
2.849000 NPCFootScuffLeft
3.003000 NPCFootScuffRight
3.164000 NPCpairedStop
3.166667 NPCPairEnd

どういうわけか、攻撃側はKillMoveEndイベントが発火します。とはいえ、攻撃側なので影響はなさそうです。

操作を改善する

MCMでバックスタブを有効にすると、プレイヤーにCH_BackStabDetectAbilityというスペルが付与されます。

このスペルはプレイヤーのPowerAttack_Start_endイベントを検知したら、CH_BackStabSpellというタッチ式のスペルを詠唱します。タッチ式なので相手を正面に捉え、十分に接近する必要があります。

CH_BackStabSpellが相手に着弾すると、バックスタブのアニメーションを再生する、という流れになっています。

角度の検査はCH_BackStabSpellにあります。

問題は、バックスタブを仕掛けるために攻撃するという点にあります。バックスタブが不発になった場合は、そのまま意図しない攻撃が出てしまうので、ストレスになります。逆に、あえて通常の攻撃をしたかったり、パワーアタックを入れたかったり、MCOでコンボを入れたかったとしても、バックスタブに化けてしまうこともあります。

要はCH_BackStabSpellを発動すればいいので、バックスタブキーを用意して、CH_BackStabSpellを詠唱するようにしたところ、上記の問題が解決できました。

結局どうなったのか

いろいろ試しましたが、再生できないときはまったく再生できないという状況はかわりませんでした。

キルムーブ発生率を変更するModがありますが、発生率を100%にしても、実際には発動しないことがあります。おそらくは何かしらの条件で絶対に再生できない状況というものがあり、発生率を100%にしようとすることがそもそもが無理な話なのだと思われます。その状況は戦闘に関係しているのだと思います。マルカルスのシーンが不発しないのは、Actorが非戦闘状態だからであり、これが戦闘状態になると話が変わってくるのだと思います。

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