takeyohのおぼえがき

気になったこと、試したことの記録です。

ac_car_scriptable_displayを活用した音源の操作方法

assettocorsaは、car modの中にsfxフォルダというのがあり、ここに音源に関するbankファイルとその中に入っているイベントのIDが並んだGUIDs.txtというファイルがあります。このbankファイルとGUIDs.txtは2つで一組になります。
GUIDs.txtに記載されている
event:/XXXXとなっている行が、bankファイルに格納されている音源の場所を指定しています。
たとえば、event:/cars/(carID)/engine_intは車内視点時用のエンジン音、event:/surfaces/grassだと、草の上を走った時の音、とかそういうことですね。
ゲーム起動時には、AI車両を含め、各車ごとにこの2つの音源ファイルが読み込まれ、車の状態に合わせて、音を制御し出力しています。
その際、車外視点でのボリュームを1とすると、車内視点は0.25(外視点の4分の1)の大きさで再生されるように設定されています。
車の中は気密性が高いから、音が小さくなることを再現しているんですね。

ここまでは、前置きというか前提でして、課題はこれから。
今回S2000を作成し、屋根が開くようにしました。
そうすると、車内視点の音量は、0.25倍ではなく、1倍にしたいわけです。
音量を0.25倍→1倍にするための覚書となります。

まず、音量を調整するのに一番簡単な方法は、luaアプリを使って制御する方法です。
ac.setAudioVolume関数が使えます。

---Sets audio volume for given channel, value from 0 to 1. If channel is not recognized, does nothing.
---@overload fun(value: number)
---@param audioChannelKey ac.AudioChannel
---@param value number @Value from 0 to 1.
---@param carIndex integer? @If set, applies volume as a multiplier to a specific car (currently supported: \`'dirt'\`, \`'engine'\`, \`'opponents'\`, \`'surfaces'\`, \`'transmission'\`, \`'tyres'\`, \`'wind'\`). Default value: -1.
function ac.setAudioVolume(audioChannelKey, value, carIndex) end

audioChannelKeyには音量を変更したいac.AudioChannelのパラメータを入力。

---@alias ac.AudioChannel
---| `ac.AudioChannel.Main` @Value: 'main'.
---| `ac.AudioChannel.Rain` @Value: 'rain'.
---| `ac.AudioChannel.Weather` @Value: 'weather'.
---| `ac.AudioChannel.Track` @Value: 'track'.
---| `ac.AudioChannel.Wipers` @Value: 'wipers'.
---| `ac.AudioChannel.CarComponents` @Value: 'carComponents'.
---| `ac.AudioChannel.Wind` @Value: 'wind'.
---| `ac.AudioChannel.Tyres` @Value: 'tyres'.
---| `ac.AudioChannel.Surfaces` @Value: 'surfaces'.
---| `ac.AudioChannel.Dirt` @Value: 'dirt'.
---| `ac.AudioChannel.Engine` @Value: 'engine'.
---| `ac.AudioChannel.Transmission` @Value: 'transmission'.
---| `ac.AudioChannel.Opponents` @Value: 'opponents'.

たとえば、'main'とか、'engine'とか指定しても良いですし、エイリアスが設定されているので、`ac.AudioChannel.Main`と書いてもよいです。
valueは音量(0~1)、carIndexは対象の車(自車なら0)です。

なのですが、このac.setAudioVolumeという関数は、car modで使えるluaライブラリには含まれていません。
ちょっと脱線ですが、assettocorsaではいろんなところでluaスクリプトが使えますが、それぞれ別々のluaライブラリが設定されており、それを変更することはできません。
(assettocorsaインストールフォルダ)\extension\internal\lua-sdkの下を見ていただくと、ac_で始まるフォルダがいくつかあって、それぞれの中にlib.luaが入っています。
luaアプリで使用されるライブラリはac_appsの下にあるlib.luaですが、car modで使用されるライブラリは、物理制御系ならac_car_cphys、映像、音制御系ならac_car_scriptable_displayが使われます。
で、今回のacAudioChannel関数は、ac_appsのlib.luaには定義されていますが、ac_car_cphysとac_car_scriptable_displayには定義が無いため、使えないということになります。

じゃあ、どうやってcar mod関係のluaスクリプトから、環境音を制御するのか?
代わりにやっと見つけた関数がac.CarAudioTweak.setVolumeです。

>
      • Set volume multiplier. Overrides `[AUDIO_VOLUME]` value from car config.
      • @param eventID ac.CarAudioEventID @ID of a target event.
      • @param value number @New value from 0 to 1 (100%), can go above 1 as well.

function ac.CarAudioTweak.setVolume(eventID, value) end<||
この関数なら、ac_car_scriptable_displayにも定義があるので使えます。
eventIDはac.CarAudioEventIDから指定できます。

>
      • @alias ac.CarAudioEventID
      • | `ac.CarAudioEventID.EngineExt` @Value: 0.
      • | `ac.CarAudioEventID.EngineInt` @Value: 1.
      • | `ac.CarAudioEventID.GearExt` @Value: 2.
      • | `ac.CarAudioEventID.GearInt` @Value: 3.
      • | `ac.CarAudioEventID.Bodywork` @Value: 4.
      • | `ac.CarAudioEventID.Wind` @Value: 5.
      • | `ac.CarAudioEventID.Dirt` @Value: 6.
      • | `ac.CarAudioEventID.Downshift` @Value: 7.
      • | `ac.CarAudioEventID.Horn` @Value: 8.
      • | `ac.CarAudioEventID.GearGrind` @Value: 9.
      • | `ac.CarAudioEventID.BackfireExt` @Value: 10.
      • | `ac.CarAudioEventID.BackfireInt` @Value: 11.
      • | `ac.CarAudioEventID.TractionControlExt` @Value: 12.
      • | `ac.CarAudioEventID.TractionControlInt` @Value: 13.
      • | `ac.CarAudioEventID.Transmission` @Value: 14.
      • | `ac.CarAudioEventID.Limiter` @Value: 15.
      • | `ac.CarAudioEventID.Turbo` @Value: 16.
      • | `ac.CarAudioEventID.WheelLF` @Add 0-based index to this value for Nth wheel.
      • | `ac.CarAudioEventID.WheelRF` @Value: 21.
      • | `ac.CarAudioEventID.WheelLR` @Value: 22.
      • | `ac.CarAudioEventID.WheelRR` @Value: 23.
      • | `ac.CarAudioEventID.SkidIntLF` @Add 0-based index to this value for Nth wheel.
      • | `ac.CarAudioEventID.SkidIntRF` @Value: 31.
      • | `ac.CarAudioEventID.SkidIntLR` @Value: 32.
      • | `ac.CarAudioEventID.SkidIntRR` @Value: 33.
      • | `ac.CarAudioEventID.SkidExtLF` @Add 0-based index to this value for Nth wheel.
      • | `ac.CarAudioEventID.SkidExtRF` @Value: 41.
      • | `ac.CarAudioEventID.SkidExtLR` @Value: 42.
      • | `ac.CarAudioEventID.SkidExtRR` @Value: 43.

<||
valueは0~1を指定できると書かれています。
やってみると、確かに音量を変更することが出来たのですが、ここで新たな問題が。
このvalue0~1の指定は、室内の音量が0.25倍に制御された状態が1なのです。
だから、valueに1を指定するとデフォの0.25倍、valueに0.5を指定するとさらに半分の0.125倍の音量になってしまうのです。
屋根を空けたら、外の音量にしたいわけなので、車内用の音を0.25倍より大きくできないじゃん・・・!

でも、もしかして?と思って、指定を無視し、valueを4に設定してみたところ、なんと反映されました!
元々0.25倍に制御されている音源を4倍にするので、外音源の1倍と同じ音量になりました。

S2000の屋根の開閉に合わせて、エンジン音を変更するスクリプトを例に掲載します。
(実際にはここからさらに手を加えますが、わかりやすいように単純化しています。)

lua >

local roof = false

function update(dt)
if ac.getCar().extraE == true and roof == false then
ac.CarAudioTweak.setVolume(ac.CarAudioEventID.EngineInt,4)
roof = true
end
if ac.getCar().extraE == false and roof == true then
ac.CarAudioTweak.setVolume(ac.CarAudioEventID.EngineInt,1)
roof = false
end
end

extraEキーを押すと、屋根が開くようにアニメーション設定しているので、extraEがtrueになったら、ac.CarAudioEventID.EngineInt(車内用のエンジン音源)の音量を4に、extraEがfalseになったら1に戻すというスクリプトになります。

これで、とりあえずcar modに付随する環境音の音量を制御することはできるようになりますが、track側からの音量の変更はやはりできません。(これは仕方がないか)


あと、ここからは番外編。上記はcar modに設定された車の環境音の音量を制御するための方法ですが、ac_car_scriptable_displayのlib.lua自体には、bankファイルを読み込む機能があります。
ac.loadSoundbank(soundbank, guids) 
ここでloadされた音源データとGUIDS.txtの音源は、ac_car_scriptable_display用のlua script内でも自由に再生・停止させることが可能ですし、音量も簡単に変更できます。今回のS2000でも、ドア開閉時の音はac_car_scriptable_displayのlua script内で、別音源bankファイルをloadして再生・停止を制御しています。

以上です。
/* -----codeの行番号----- */