一つ前の覚書で書いた通り、現在のCSP(具体的には1.77以降)では、luaスクリプトを使って、wavやmp3などの音データを再生できることがわかりました。
同時に、今までpythonで書いていたアプリケーション類が、lua scriptでも書けるようになっています。ってことは、lua scriptでアプリを作れば、外部アプリを使わなくてもウィンカーの音が鳴らせるのでは?ということで覚書です。
最初はpythonを使って挑戦しました。音を出すのは簡単だったのですが、問題はウィンカーの点灯消灯のステータスが認識できないことでした。pythonのライブラリではCSPの拡張機能が認識できません。しかし、lua scriptバージョンであれば、CSPの拡張機能も認識できます。すばらしい~!
どういうアプリなのかの確認とアプリのダウンロードはこちらからできます。
インストールすると、assettocorsaのフォルダの下でapps/lua/blinkerというフォルダができます。
blinker.luaがスクリプト本体、blinker.mp3がウィンカーの音、icon.pngはゲーム開始後の右メニューに表示されるときのアイコンの絵、manifest.iniは設定ファイル(みたいなもの)です。
まずmanifest.iniの一部WINDOWセクションです。
[WINDOW_...]
ID = main
NAME = Blinker Sound
ICON = icon.png
FUNCTION_MAIN = windowMain
SIZE = 400, 300
これは、このアプリの設定画面を表示するためのウィンドウ設定です。これが無いと、画面に文字や画像などの表示ができません。
続いて、blinker.luaの中身です。
local carSounds = ui.MediaPlayer()
local soundSetting = 0
-- soundSetting 0:road or street only 1:all cars
local soundVolume = 1
local value, changed
ここまでは各種変数の宣言パートです。
一番上のui.MediaPlayer()が使えるようになったのが一番大きなポイントですね。
soundSettingはroad,streetクラス車のみ音を出すか、全車音を出すかの判別フラグ。
soundVolumeはウィンカーの音量。(1は100%のことです。)
local mp3File = ac.getFolder(13) .. "\\" .. ac.getCarID(0) .. "\\extension\\blinker.mp3"
local wavFile = ac.getFolder(13) .. "\\" .. ac.getCarID(0) .. "\\extension\\blinker.wav"
local soundFileif io.fileExists(mp3File) then
soundFile = mp3File
elseif io.fileExists(wavFile) then
soundFile = wavFile
else
soundFile = './blinker.mp3'
end
carSounds:setSource(soundFile):setAutoPlay(false)
ここはウィンカーの音を選択しているパートです。
自車のcar modフォルダのextensionフォルダ内にblinker.mp3かblinker.wavのどちらかのファイルが存在すればそのファイルを、無い場合はアプリのフォルダ内にあるblinker.mp3を選択しています。(soundFile変数に使う音ファイルのパスを格納し、carSoundsにセット。)
setAutoPlayはtrueにするとこの処理時に即時音が再生されます。今回はウィンカーがついている時だけ音を出したいので、ここではfalseにしてます。
次は一つ飛んで、windowMainパート
function script.windowMain(dt)
if ui.radioButton('road & street car only', soundSetting==0) then
soundSetting = 0
end
if ui.radioButton('all cars', soundSetting==1) then
soundSetting = 1
end
value, changed = ui.slider('volume', soundVolume, 0, 1, '%.2f')
if changed then
soundVolume = value
end
ui.text('sound file')
ui.text(soundFile)
end
ここでは、manifestで設定したウィンドウの中身を設定しています。
具体的にはラジオボタン2つ(road, streetクラス車のみか、全車を選択)と、ボリュームを設定するスライダー(0%~100%)、それと、選択された音ファイルを表示しています。
radioButtonは横に表示する説明書きと、チェックがついた状態にするかどうかの判別文が引数にあり、radioButtonが押されたことをif文で判別してます。
一方、sliderはスライド後の値とスライドさせたことのフラグを変数に格納(この例ではvalueとchanged)し、フラグをチェックして値が変化したことをif文で判別しています。
ui.textは表示する文字列を引数に格納しています。
function update(dt)
if ac.getCar().isCameraOnBoard and (ac.getCar().hazardLights or ac.getCar().turningLeftLights or ac.getCar().turningRightLights) then
if soundSetting == 1 or (soundSetting == 0 and not ac.getCar().isRacingCar) then
carSounds:setVolume(soundVolume)
carSounds:play()
end
else
carSounds:pause()
end
end
最後はupdateパートです。これはゲーム中ずっとループしているパートになります。
windowMain部分で各種値を変数に格納すると、それがこのループ処理の中に反映される形ですね。
ac.getCar().isCameraOnBoardは視点がオンボード(車内)であるかどうか
ac.getCar().hazardLights or ac.getCar().turningLeftLights or ac.getCar().turningRightLightsはハザードか左ウィンカーか右ウィンカーのどれかが点いている状態であるかどうか
をチェックしていて、それをandでつないでいるので、両方の状態が満たされるときその中のルーチンが実行されます。それ以外の場合は、音を止めるcarSounds:pause()処理をします。
if文が入れ子になっていますが、中のif文はsoundSetting変数が1なら全車種なので無条件で音を鳴らし、sounrdSetting変数が0の場合は車がレーシングカーでは”ない”ことをチェックしています。
javascriptやpython、coffeeなどスクリプト系言語に触れたことがある方ならすぐ理解できると思います。(もちろんプログラミング言語をご存じの方も)
超シンプルなスクリプト構成になっているので、lua scriptによるアプリ作成のベースにもなるかと思います。参考になれば幸いです。