非プログラマのRen'Pyノート:音楽、効果音まわりのスクリプト
ノベルゲームエンジンRen'Py(以下renpy)には色々便利な昨日が標準でついており、公式マニュアルもあります。
しかし、長年の積み重ねで培われた凄まじい物量&何でもできるがゆえに専門用語も散りばめられている&実際にどう書けば動くのか不明……など、素人こと私にはちょっとハードルが高かったりしますので、よく使いそうなスクリプトをサンプルとともにまとめておきます。
予習:音のチャンネルとはつまり何なのか
これ知らなくても大体なんとかなりますが、特に「音を同時に複数鳴らしたいケース」のために知っておくと便利です。
renpyには標準で音楽・効果音・声 チャンネルがあります。自分の雑な認識では、基本的に「それぞれのチャンネルでは1つしか音が再生できない」、つまり音楽のクロスフェードとかは標準的(※)な機能ではできない。雨の効果音を再生しながらクラクションを鳴らすと雨の音が停まってしまう。という認識です。
私はこれをざっくり解決する方法としてaudioチャンネルを使っていました。なお、どうもaudioチャンネルは効果音に所属する? らしく、環境設定で効果音を調整すると反映されます。
play sound rain loop
"雨の音だよ"
play audio pupu
"↑play audio だと雨の音も鳴り止まない"
play sound pupu
"↑これだと雨の音が停まってしまうよ"
しかしaudioチャンネルは、複数の音を同時に鳴らすことができますが、音の停止ができないっぽいです。つまり長い音やループ音源には向かない。
なので、以下のような方法を使ってサウンドのチャンネルを増やすのが無難かなと思います。が……、
…………。
これだけでは何のことかまったく分からない開発者こと私のために、実際に書いてみて動いたのはこんな感じ。
init python:#以下をどこかに書く わからない人はlabel startより前
renpy.music.register_channel("soundplus", "sfx", False)
#Trueにするとループする
#sfxとは効果音のチャンネル
#soundplusっていうのは自分で任意の名前をつけられる
label start:
play sound rain
pause 1.5
"テスト"
play soundplus pupu
musicチャンネルを+1用意すれば理論上クロスフェードも可能ですね。
なお、音楽のクロスフェードを大元からいい感じにどうにかする方法はこちらに掲載されていますが難しめなので未検証です。
フェードイン・フェードアウト
フェードイン
play music yyy fadein 1.5
フェードアウト
play music yyy
pause
stop music fadeout 1.5
効果音にも音楽にも使えます。
ボリュームの調整
play sound pupu volume 0.5
上限は1.0なので、120%とかにはできないっぽい。割れちゃうし。
ただ経験上、ゲーム制作ではゲーム側でそれぞれの音量を都度調整するのではなく、元の音源そのものの音量を揃えておいた方が混乱なく作れると思います。
音楽をループさせない/効果音をループさせる
musicチャンネルとsoundチャンネルの主な違いに、同じ「play」でも標準でループする・しないが設定されているという点があります。
play music ongaku
"↑これはループする"
play music ongaku noloop
"↑これはループしない"
play sound rain
"↑これはループしない"
play sound rain loop
"↑これはループする"
便利ですが、エンドロールの音楽なんかだと1回だけ再生したいこともありますよね。
音楽をループ「させたくない」ときは 「noloop」、効果音をループさせたいときは「loop」と指定する必要があります。
音楽を一時停止後、復帰する
出だしが印象的な音楽で、物語の途中で再度冒頭から再生すると悪目立ちしてしまう場合とか、コメディっぽいシーンで有効かも。
play music ongaku
"なんかイベント"
#一時停止する
$ renpy.music.set_pause(True, channel="music")
"なんかイベント"
#一時停止おわり
$ renpy.music.set_pause(False, channel="music")
ダッキング(ボリュームの一時的な変更)
ダッキングとは、一時的にボリュームをちょっと下げてまた復帰させることを言うらしいです。
言葉で説明すると「かかってる音楽を30%くらいにフェードアウトして、ダッキング終わりに100%に戻す」自分は効果音を際立たせたいときなどに使ってます。
play music ongaku
"なんかイベント"
#ダッキングここから。1.0かけて delayとは多分フェードインアウトと同義と思われます。
$ renpy.music.set_volume(0.30, delay=1.0, channel='music')
"なんかイベント"
#ダッキングここでおわり delayとは多分フェードインアウトと同義と思われます。
$ renpy.music.set_volume(1.00, delay=1.5, channel='music')
鳴ってるか鳴ってないか判断してくれる
鳴り終わりを待って再生する「queue」
"テスト"
play sound pupu
"テスト"
queue sound pupu
覚えられないので「くえうえ」と呼んでいます。
鳴ってるかチェックして任意再生する「if_changed」
if 分岐とかでシーンjumpするけど、ジャンプ元で鳴ってたらジャンプ先でも鳴らしっぱなしにしたいときとかに使えそう。
label market_side:
play music market
"これは公式マニュアルにあるのをそのままコピペーしただけ"
jump market_main
label market_main:
play music market if_changed
"前にもここに来たことがあるか?"
jump market_main
選択肢表示時に効果音を再生する
以下のようにデフォルトの選択肢(choice menu)に書き加えると選択肢が表示されたと同時に効果音を鳴らすことができます。
screen choice(items):
style_prefix "choice"
on "show" action Play("sound","hiin.mp3") #書き加えるのはこれです
vbox:
#~以下略〜
便利すぎてカッコ良すぎる!!! つまりこれは、他のscreenでも表示と同時に音が鳴らせるので嬉しくて乱用しています。これでスクリプトがかなりスッキリします。
on "show" action Play("sound","sound.mp3")
スクリーンを隠すときにももちろん使えます。
on "hide" action Play("sound","sound.mp3")
他にも何か良さそうな小技などあれば追記します。