こんにちは、まとんです。
Soulsy HUDを使いやすくカスタマイズしようと思ったのですが、思いの外大変だったので、その手順を残しておきたいと思います。

ちゃんとビルドできるようになるまでに2日かかりました。。
通常、SKSEプラグインはC++で作成するのですが、このModはそこにRustを組み合わせるという、おもしろい使い方をしていました。
どうも作者様はRustに強い思い入れがあるみたいで、SKSEライブラリをRust化するというプロジェクトに取り組んでおられるみたいです。

Rustは触ったことないので、さっぱり分からんのです。
今回は解説というより、自分のための備忘録的な意味が強いのでご了承ください。
準備1:各種ツールのインストール
Soulsy HUDのビルドに必要な各種ツール類をインストールしていきます。

必要なものは、Soulsy HUDのGitページに記載されています。
基本的に自分の環境に合わせたインストーラーをダウンロードして、後は画面の指示に従い入れていけばOKです。
各種インストーラーの設定項目は、全てデフォルトで問題ありません。
Visual Studioが未インストールの場合、Rustのインストール時にインストールするか聞かれるのでインストールします。

この場合、英語版のVSがインストールされます。日本語のVSが欲しい場合は自分でインストールするか、Windowsのアプリ一覧から「Microsoft Visual Studio Installer」を起動し、日本語を追加しましょう。
vcpkgのインストールについて
vcpkgのインストールだけ特殊なので解説します。
コマンドプロンプトからvcpkgをインストールしたい任意のフォルダを開き、以下のコマンドを実行します。
git clone https://github.com/microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
これで、vcpkg下に実行ファイル「vspkg.exe」が作成されます。

vcpkgフォルダは環境変数のPathに登録し、パスを通しておきましょう。
準備2:Soulsy HUDのビルド準備
続いて、Soulsy HUDのビルドに必要な環境を整えていきます。
コマンドプロンプトからSoulsy HUDのソースコードを格納したいフォルダを開き、以下のコマンドを実行します。
git clone https://github.com/ceejbot/soulsy
cd soulsy
git submodule update --init --recursive
cargo update -p time ※timeクレートのビルドに失敗する場合
それぞれのコマンドについて解説します。
- git clone https://github.com/ceejbot/soulsy
Soulsy HUDのソースコードをクローンします。 - git submodule update –init –recursive
CommonLibSSE-NG(SKSEプラグインのライブラリです)をサブモジュールとしてダウンロードします。 - cargo update -p time
Rust最新版に付属するtimeクレートにはバグがあるみたいで、私の環境ではtimeクレートのバージョンを上げておく必要がありました。そうしないとビルドが失敗します。
何もせずともビルドが通るのであれば、このコマンドは不要だと思います。
ビルド
ビルドは次のコマンドを実行します。
rd /s /q build ※初回ビルド時は不要
cmake --preset vs2022-windows
cmake --build --preset vs2022-windows --config Release
それぞれのコマンドについて解説します。
- rd /s /q build
前回のビルドを削除します。初回ビルド時は実行する必要はありません。 - cmake –preset vs2022-windows
ビルドに必要な各種環境を整えます。ツールチェインやVS側のコンパイラオプションの設定なども、このプリセットでやってくれているみたいです。 - cmake –build –preset vs2022-windows –config Release
ビルドします。
ビルド後のモジュールは「build\Relase」配下にできます。この中のdllをオリジナルとdllと入れ替えればOKです。
やりかったこと
以上でSoulsy HUDをビルドするところまでできました。

まとめるとこれだけのことなのですが、gitに詳しいビルド手順が載ってなかったり、そもそも私がRustの知識を全く持ってなかったため、すごい遠回りをしてしました。。
で、ここまでして何をしたかったの? ということなんですが、Soulsy HUDのちょっとした誤動作を修正したかったのです。
サイクルキーの誤動作を防止したい
こちらの記事でも紹介した通り、Soulsy HUDは大変使いやすく、私のスカイリムには欠かせないModの一つなのです。
が、サイクルキーと他のキーを同時押しするとサイクルキーも反応してしまうという、ちょっと困った動きがあります。

例えば、私はゲームパッドの→を右手装備のサイクルキーに割り当て、RB+→をホットキーに設定しています。
この場合、ホットキーをトリガーしたときに右手装備も切り替わってしまいます。
切り替わった装備はまた元に戻せば良いので、そんなに深刻ではないのですが、地味にストレスなので直せるなら直したいなあと思っていました。
原因
この現象が発生する原因は、Soulsy HUDが自分の管理下にないキーを一切検知していないことにあります。
なので、サイクル登録やポーション使用にも関係していないキーは、押されていてもサイクルキー単発押しという認識なっていました。
直し方
直し方ですが、control.rsのサイクルキーの有効チェックに以下のコードを入れました。
control.rs
pub fn handle_key_event(&mut self, key: u32, button: &ButtonEvent) -> KeyEventResponse {
...
// From here on, we only care if the key has gone up.
if tracked.state != KeyState::Up {
return KeyEventResponse::handled();
}
+ // 押下中のキー数をチェック
+ let pressed_count = self.tracked_keys.values()
+ .filter(|k| {
+ matches!(k.state, KeyState::Pressed | KeyState::Down)
+ && k.press_start.map_or(false, |start| start.elapsed() <= Duration::from_secs_f32(5.0))
+ })
+ .count();
+
+ // キーアップしているのに他に押されているキーがあれば処理しない
+ if pressed_count >= 1 {
+ return KeyEventResponse::default();
+ }
Soulsy HUDは長押しを認識するので、キーアップがサイクルキーの発動タイミングになります。
なので、サイクルキー発動OK(キーアップされ、他に押されているキーがないはず)となった後に、まだ押されているキーがあるようなら発動をキャンセルするという動きにしました。
それと説明しづらいのですが、このModは、ボタンが押され始めたタイミングは認識しているのですが、キーアップした時間は監視していません。
そのため、次にそのキーが押されるまでMod内では「キーはずっと押しっぱなし」という扱いになっています。
それだと「今押されているか?」という判定がうまく機能しないので、直近5秒以内に押し続けられているキーがあるかという条件で判定することにしました。

本当は同時押しだけみれば良いので、数フレーム分のキープレスだけ見たかったのです。
しかし、シャウトや魔法など、長押し前提の操作とかみ合わなくなるので、5秒というちょっと長めの時間にしました。
まとめ
たったこれだけの修正をするのに、えらい時間を使ってしまいました。
ただ、その甲斐あってゲームプレイがすこぶる快適になったので、がんばってよかったと思います。
また、Rustは初めて触ったのですが、初めてでも結構直感的扱えて良い言語だと思いました。
ただちょっと欠点があって、ビルドがすごく遅いです!

Rust + C++という構成のせいかもしれませんが、dllをたった一つ作るだけなのに数分かかるのは、ちょっときついです。
おかげで長押し時間の微調整など、何度もトライアンドエラーしたい作業が大変でした。。
いろいろと良い経験になりました。疲れた。。


コメント