開発日誌

すべての記事

[ テクニック ] ブラウザプレイでBGMと演出のズレをなくす方法

2025-12-09 00:00:06

本記事は「ゲーム制作アドベントカレンダー(旧ツクールアドベントカレンダー)Advent Calendar 2025」12月9日分の投稿記事です。

今年2025年はついに、5年にわたって制作してきた長編大河RPG『王国の英雄』を完成させ、公開しました。

今回は、その時にエンディングのイベントを作った経験から、エンディングの演出でよくある、画面上のキャラの動きとBGMとをシンクロさせる時の注意点とその対処法について解説します。

エンディングに限らず、BGMと演出を同期させるようなシーンで役立ちます。

またブラウザプレイで顕著ですが、ダウンロード版でも多少の遅延は発生しうるので、対策するに越したことはありません。

BGMと演出の同期

エンディングでよくある演出が、メッセージを表示せずキャラの動きだけでシーンを連続して見せるような演出。これまでの冒険の回想や主人公たちのその後の様子などが、いわゆる「人形劇」で次々と流れていく演出です。

この時、BGMの盛り上がりや転調のタイミングが演出とシンクロしていると、とても印象的に映ります。

しかし、どんなにタイミングをバッチリ合わせたとしても、バックグラウンド処理の影響や画像等の読み込みの遅延により、微妙にズレが発生します。

制作時は自分のPCのローカル環境でテストプレイするためなかなか気付きませんが、スペックの低いPCでプレイした場合や、特にPLiCyなどブラウザプレイの場合には、顕著な遅れが出てしまいます。

そういうのを「気にしない」というのも一つの方法ですが、せっかくBGMと演出とを合わせたのなら、その状態で見てほしいものです。それにBGMが微妙にズレていると、遅延のせいとは知らないプレイヤーには「残念」と映ってしまうでしょう。せっかくの苦労が水の泡になってしまいます。

ではどうすればいいのか? 可能な限りズレを解消する方法について解説します。

エンディングでよくある演出と言っていますが、それ以外でもオープニングやその他、BGMと動きがシンクロするようなシーン全般で使えるテクニックです。拙作『王国の英雄』でもエンディングのほか、オープニングムービーや三人娘のダンスショーのシーンなどで用いています。

▲『王国の英雄』のダンスショーシーン、BGMとダンスを合わせている

なお、通常の「文章の表示」で台詞を表示させる場合、制御文字の\^で自動メッセージ送りをしていない限りは、プレイヤーの操作によってタイミングは全く変わってくるので、そもそもBGMとの同期には合いません。ご注意ください。

早送りの禁止

まず忘れてはならないのが、RPGツクールに標準機能として備わっている、早送り機能の無効化です。

イベント中に決定キーを押しっぱなしにしていると、メッセージが早送りされるのはもちろん、各キャラの動きも倍速になります。しかしBGMまでは倍速では流れないため、どんどんズレていってしまいます。

そこで、決定キー押しっぱなしによる倍速化機能を、該当シーン中は無効化しておく必要があります。

この早送りの無効化は、イベントコマンドではできないので、プラグインに頼ることになります。

同様の機能を持つプラグインは多数ありますが、拙作プラグイン「イベント早送り無効化プラグイン(PANDA_DisableFastForward.js)」でも高速化のON/OFFが簡単に切り替えられます。

スイッチを一つ用意してプラグインパラメータで指定し、該当シーンの直前でそのスイッチをONにし、終わったらOFFにすれば、該当シーン中は早送りができなくなります。

画像の先読み

次に必要なのは、画像の先読み(プリロード)です。

ローカルの環境ではほとんど気にはなりませんが、ブラウザプレイ環境の場合、サーバーやネットワークに起因する画像の読み込みの遅延は顕著に起こります。

ツクールには使用する画像ファイルをキャッシュしておく仕組みがあります。過去記事「画像の先読みを改善して画像表示のラグ解消」で紹介したように、RPGツクールMZではイベントの開始時にそのイベントで使用される画像をあらかじめ読み込んでキャッシュする仕組みになっています。

しかし、キャッシュが効くのはイベントコマンドの200行目までに登場する画像となっており、長いイベントだと途中からキャッシュが効かなくなってしまいます。エンディングのイベントなどは長くなりがちなので、この影響を顕著に受けます。

それを改善するのが、上記の記事で紹介している拙作「画像先読み改善プラグイン(PANDA_ImagePreLoad.js)」です。

このプラグインを導入すると、200行という制限が解除されるほか、通常では先読み対象にならない「遠景の変更」や「移動ルートの設定」中の「画像の変更」も対象になります。

1つのマップに全て収める

意外と盲点なのが、マップ間の移動を行うと、マップの読み込みが走って遅延が生じる点です。

連続で回想シーンを流すような演出の場合、各回想シーンごとに1つのマップで構成し、場所移動と自動実行イベントでシーンを繋いでいくことが多いですが、そのような構成にすると、マップ移動の際にマップの読み込みが行われ、そこで遅延が発生します。

▲『王国の英雄』エンディングのマップ、1マップに全シーンを詰め込んでいる

それを防ぐためには力業ですが、そのシーンで使用するマップを、全て1つのマップに収める方法です。

同一マップ内の場所移動であればマップの読み込みは発生しないので、1つのマップ、1つの自動実行イベントに全てのシーンを収めます。そうすれば解決します。

次のマップをプリロードするプラグインなども存在しますが、さらにその先のイベント内での画像の先読みなどもあるため、1つのマップに押し込めてしまうのが最も手っ取り早いです。

ただその場合、タイルセットの異なるマップを1マップに統合する際は、場所移動時の暗転中にイベントコマンドの「タイルセットの変更」で切り替えてやる必要があります。

先述の「画像先読み改善プラグイン」は「タイルセットの変更」によるタイルセット画像のプリロードには対応していないため、イベント冒頭でフェードアウト中に「タイルセットの変更」を行って、キャッシュに保存しておく必要があります。

ウェイトで時間調整

そして、ここが最大のポイントです。

上記の対策を行っても、PCのバックグラウンドでの処理などの影響により、秒単位以下の遅延は生じます。これはブラウザプレイに限らず、ローカルの環境でも起こりえます。

1~2フレーム(1フレーム=1/60秒)の遅れならまだしも、それが累積して数フレーム以上の遅れになると、BGMとの同期に明らかなズレが見られます。

その時の対策として有効なのが、ウェイトで時間調整をする方法です。

この手の演出を作る場合、たいてい数十フレームから2~3秒程度のウェイトが入ります。このウェイトの長さが数フレーム短くなったところで、基本的に演出には影響がありません。

そこで、ウェイトの時間を調整してBGMのタイミングを合わせるのです。そうすれば、数フレームのズレが起きていたとしても、ウェイトのところでズレが解消されるため、結果としてズレを最小限に抑えることができます。

RPGツクールのコアスクリプトでは、AudioManager.saveBgm().posで現在のBGMの再生位置を秒数で取得することができます。この値が一定値になるまで、1フレームずつのウェイトをループ処理で繰り返し、一定値になったらループを抜けるようにすれば、ウェイトで時間調整が可能です。

具体的には、まず以下のようにして、ちょうど良いタイミングにおけるBGMの再生位置を取得します。

◆ウェイト:90フレーム
◆変数の操作:変数A = AudioManager.saveBgm().pos * 1000
◆文章:なし, なし, ウィンドウ, 下
:  :\V[1]

再生位置の数値の単位は秒ですが、実際の値はフレーム単位まで取得されるため、返される値は小数点以下の値になります。そのままだとイベントコマンドで扱いにくいので、1000倍して整数で扱えるようにしています。

ちょうど良いタイミングにおけるBGMの再生位置が取得できたら今度は以下のようにして、その位置になるまでループするようにします。

◆ウェイト:45フレーム
◆ループ
 ◆変数の操作:変数A = AudioManager.saveBgm().pos * 1000
 ◆条件分岐:変数A < 57500
  ◆ループの中断
 :分岐終了
 ◆条件分岐:変数A >= 58650
  ◆ループの中断
 :分岐終了
 ◆ウェイト:1フレーム
:以上繰り返し

全体のウェイトが90フレームとして、半分の45フレームは必ず入れるようにします。これがないと、遅延が激しかった時にウェイトがなくなってしまうため、それはそれで演出として違和感が出てしまいます。どのくらい強制ウェイトを入れるかは、半分くらいを目安に感覚で構いません。

再生位置の値は1/60フレーム単位=16.66…と端数が出るため、適当にキリの良い値に切り捨てて、その値よりも現在の再生位置が大きければ、ループを抜けてウェイトを終了するようにしています。ぴったりの値にすると、誤差で1フレームズレる可能性があります。

また、BGMがループすると再生位置は0にリセットされます。そのため、何らかの理由で大幅に遅延し、BGMが周回遅れになっていると、BGM1周分に近いウェイトが発生することになります。しばらく動きが止まることになって、それはBGMとのズレ以上に不自然なため、そういう場合は同期を諦めて、再生位置が一定値以下だった時も即座にループを抜けるようにしています。

こういった調整を、ある程度の長さのウェイトがあるところで何カ所か仕込んでおけば、途中で遅延が発生してもすぐに解消されます。

フォーカス喪失対策

RPGツクールの、というかPCアプリケーション全般の仕様として、そのアプリ(ゲーム)のウィンドウがフォーカスを失ってアクティブでなくなると、画面の更新は停止する一方、BGMは再生され続けます。そのため画面の動きとBGMに著しいズレが生じます。

これは特に、全画面表示をせずにマウスで操作をしていると、弾みでウィンドウ外のところをクリックしてしまったりして起こりがちです。そのほか、スクリーンショットを撮ろうとして別のアプリを立ち上げたりすると起こります。

それへの対策プラグインも存在します。

mattuup様の「音声強制停止プラグイン(MAT_AudioFocusResume.js)」を導入すると、ウィンドウがアクティブでない時にBGMの再生を停止できるようです。

また逆に、はどはど様の「H2A_DontPauseWhenBlur」を導入すると、ウィンドウがフォーカスを失っても動きが停止しないようにできるようです。

『王国の英雄』ではここまでは導入していないのですが、気になる場合は導入すると完璧でしょう。

最後に

重要なシーンでキャラの動きとBGMとをシンクロさせるのは、かなり労力がかかりますが、きれいにハマると印象に残ります。

しかし、それが環境によってズレてしまうとなると、せっかくの労力がもったいないばかりか、ズレのせいで逆に残念な演出になってしまいます。

特にPLiCyをはじめとするブラウザプレイでは遅延によるズレが顕著なため、今回挙げた対策は非常に有効に働きます。また、ダウンロード版でも多少のズレは発生するため、対策しておいて損はないはずです。

せっかくの手間が無駄にならないよう、さらにもう一手間加えることで、完璧なシーンに仕上げましょう!

では、最後まで読んでいただき、ありがとうございました。

コメント
お名前
コメント
※ 確認画面はありません。