このマニュアルについて
このマニュアルでは、ローディング画面とオブジェクトプールの設定方法を解説します。「シーンを切り替えたときに一瞬固まる」「暗転が明けてからオブジェクトがパラパラ出てくる」「弾をまとめて撃つとそこだけカクつく」といった、読み込みと生成が原因のつまずきを減らすための機能です。
どちらも読み込みのタイミングをずらすという同じ狙いの機能で、ローディング画面の進捗にはオブジェクトプールの事前生成も含まれます。あわせて設定すると効果がわかりやすくなります。
ACTION GAME MAKER での読み込みの概要
読み込みに関わる仕組みは 3 つあり、必要な設定量が違います。
| 仕組み | 何をするか | 必要な設定 |
|---|---|---|
| シーンの非同期ロード | シーンの読み込みを裏側で進め、本体の処理を止めない | なし(常に有効。オン/オフの設定はありません) |
| ローディング画面 | ロード中に自分で作った画面を表示する | シーンを作り、設定で 選ぶだけ |
| オブジェクトプール | オブジェクトの実体を先に作っておき、消えたら捨てずに使い回す | ノードを 1 つ置くだけ |
非同期ロード自体は何も設定しなくても働いています。 ロードが裏で進むおかげで、ローディング画面はロード中もアニメーションし続けられますし、遷移先のシーンが実際に描画できる状態になってから画面が切り替わります。
オブジェクトプールが狙っているのはインスタンス生成にかかる時間の削減です。メモリの節約や断片化対策ではありません。
ローディング画面
設定のしかた
- マップ一覧の「+ 新規作成」を押し、種類で「ローディングシーン」を選んで名前を付けます。
res://loadingscenesに作られ、そのまま編集できます。 - 「設定」メニュー →「基本的な設定」を開きます。
- 「ローディングシーン」の「有効」をオンにします。
- 「シーンのパス」のプルダウンから 1 で作ったシーンを選びます。
以上です。撤去のタイミングや、遷移の種類ごとの設定は必要ありません。
プルダウンにはプロジェクト内のローディングシーンが並びます(ルートが LoadingScene のシーンを自動で拾います)。「指定なし」に戻せば未設定になります。
「有効」をオフに戻せば、ローディング画面を使わない従来どおりの挙動になります。
置き場所を変えたい場合は、同じ「基本的な設定」の素材フォルダの欄で「ローディングシーン」のフォルダを変更できます。
編集のしかた
作ったローディングシーンは、マップやメニューと同じマップ制作ビューで編集します。マップ一覧の種別プルダウンを「ローディングシーン」にすると一覧に出ます。
レイヤードックのルート行は「ローディング設定」で、その「+」から置けるのは次の6種です。ローディング中はゲームが動いていないため、表示物とアニメーションだけに絞っています。
スプライト / 単色矩形 / アニメーション / ラベル / リッチテキスト / ナインパッチレクト
マップと違いレイヤーはありません。要素はルート直下に並びます。
ルートノードの型
何でも構いません。 CanvasLayer / Control / Node2D などをそのまま使えます。一番手前に表示する処理はエンジン側で行うので、layer の調整も不要です。マップ一覧から作った場合は LoadingScene になります。
GameScene / MenuScene / CoreScene をルートに持つシーンだけは指定できません。これらはゲーム側が管理するシーンで、同時に 2 つ存在させられないためです。指定するとログにエラーが出て、ローディング画面は表示されません。
ロードの開始・完了を受け取りたい場合と、ビジュアルスクリプトで動くキャラクターを置きたい場合は、専用の LoadingScene を使います(後述)。
置くだけで動くもの
ローディング画面のシーンに置くだけで、エンジンが面倒を見ます。つなぐ設定は要りません。
| 置くもの | どうなるか |
|---|---|
シンプルゲージ / イメージゲージ / ProgressBar |
エンジンが値を更新します。ノードの最小値/最大値をそのまま使うので、既定の 0〜100 のままで動きます |
AnimationPlayer に hide という名前のアニメーション |
撤去時に再生され、再生が終わってから画面が消えます(loading_out という名前でも同じです) |
AnimationPlayer の自動再生 |
ロード中ずっと動き続けます。ゲームがポーズ状態でも止まりません |
進捗バーは Range を継承したノードなら何でも使えます。ACTG のシンプルゲージ/イメージゲージもこれに含まれるので、そのまま置けば進捗が出ます(表示する変数を指定していないゲージは、外から書かれた値をそのまま表示します)。
ただしツリー順で最初に見つかった 1 つだけが更新されます。複数のバーへ配りたい場合は、ルートのスクリプトで set_progress を受け取ってください(引数は 0.0〜1.0 です)。set_progress を実装すると、ゲージの自動更新は止まります(二重に触らないようにするためです)。
hide アニメーションを置かなかった場合は、エンジンが用意した暗幕で自動的にフェードします。
hide のループはオフにしてください。 ループしているとアニメーションが終わらず、完了の通知が来ません。エンジンはループ設定を検出するとログで知らせ、暗幕での撤去に切り替えます。
ビジュアルスクリプトで動くキャラクターを置きたい場合だけは、ルートの型を LoadingScene にする必要があります(次の項を参照)。
ルートを LoadingScene にすると増えること
ローディング画面のルートには LoadingScene を指定できます。指定は任意で、設定項目は持っていません。指定すると次の 2 つができるようになります。
| できること | 内容 |
|---|---|
| ロードの通知を受け取る | 進捗の変化・ロードの開始・完了を signal で受け取れます |
| ビジュアルスクリプトのキャラを動かす | 子に置いたビジュアルスクリプト付きのオブジェクトが、通常のシーンと同じように動きます |
2 つめは LoadingScene が子孫を走査して登録するため、ルートが CanvasLayer などのままでは動きません。 ローディング中に歩き回るキャラを置きたい場合は LoadingScene にしてください。
逆に、前の項に挙げたもの(進捗バーの自動更新、hide による撤去演出、自動再生、暗幕、消えるタイミング、set_progress)はルートの型に関係なく動きます。「進捗の表示を自分で加工したいだけ」なら set_progress を実装すれば済むので、LoadingScene は必要ありません。
消えるタイミング
次がすべて揃うと消えます。設定項目はありません。
- 遷移先シーンのロードが終わった
- 遷移先シーンが画面に配置され、動き始めた
- 配置後に 2 フレーム描画された
- オブジェクトプールの事前生成が終わった
- 最低表示時間(0.3 秒)が経過した
3 番目が「暗転が明けてからオブジェクトが出てくる」現象への対策です。ローディング画面の裏でシーンを温めてから消すので、消えた直後からすぐ遊べます。
遷移先シーンは、撤去が決まるまで動き出しません。 事前生成の待ち時間ぶんゲームが見えないところで進まないようにするためです。動き出すのは撤去演出(暗幕の閉じ、または hide)が始まる時点なので、画面が隠れている間に初回フレームが走り、見え始めるときには表示が確定しています。
ゲームシーンに設定した BGM も撤去まで待ちます。 画面がまだ出ているうちに BGM だけ先に始まることはありません。
5 番目は、ロードが一瞬で終わったときにローディング画面がチラつくのを防ぐためのものです。この 0.3 秒は暗幕が開ききってから測るので、「一瞬出てすぐ消える」ことはありません。
出現と消滅のフェード(暗幕)
ローディング画面がいきなり出ていきなり消えるとチカチカして見えるため、エンジンが暗幕を開閉して、切り替わる瞬間は必ず画面が単色になるようにしています。
| 動き | 長さ | 色 |
|---|---|---|
| ローディング画面が現れる | 0.2 秒 | 遷移前演出の色に合わせます |
| ローディング画面が消える | 0.2 秒 | 遷移後演出の色に合わせます |
| 遷移先シーンが現れる | 遷移後演出の長さ(最低 0.2 秒) | 遷移後演出の色に合わせます |
最後の「遷移先シーンが現れる」は、シーン遷移エディタで設定した遷移後演出(明転)の長さをそのまま使います。遷移後演出を「なし」にしていても、カットにならないよう最低 0.2 秒はフェードします。
遷移後演出をスライド系(SLIDE_UP など)にしている場合は、暗幕が指定した方向へ退くワイプになります。「新しいシーンの画像が動いてくる」本来のスライドは再現できません(シーンの中にカメラがあるため、シーンをずらしてもカメラごと動いて画面上は動かないためです)。方向は設定どおりに尊重されます。
hide アニメーションを自分で置いた場合は、消える以降の演出は作者側に任せます(暗幕は使いません)。二重にフェードするのを避けるためです。
進捗バーの動きについて
進捗バーは完了までの見込みを表すもので、厳密なパーセンテージではありません。
| 区間 | 内容 |
|---|---|
| 0〜60% | リソースのロード中 |
| 60〜85% | ロード完了からシーン配置まで |
| 100% | 撤去が確定 |
各区間の上限へ向かって滑らかに伸びていき、段階が進むと加速します。巻き戻ることはありません。 また 100% で止まったまま待たされることもありません。
オブジェクトプールの事前生成がある場合は、そこから 99% までを事前生成の進捗が埋めます。 こちらは実際に作った数の割合なので、時間による滑らかな伸びではなく生成の進み方そのままに動きます。事前生成が始まる位置は最低 30% からで、それより手前で始まることはありません(ロード中にバーが動かず止まって見えるのを避けるためです)。
厳密な値にできないのはエンジン側の制約です。ロードの途中経過を取得できず、さらに遷移先のシーンは近傍シーンとして先読みされていることが多く、ロード自体が一瞬で終わってしまうためです。
起動時の流れ
起動すると、まず ACTION GAME MAKER のスプラッシュが 1 秒表示され、そのあとローディング画面へ進みます。
スプラッシュを出している間もロードは裏で進むので、スプラッシュを見せるぶん起動が遅くなることはありません。 最初のシーンが軽く、スプラッシュ表示中にロードが終わった場合は、ローディング画面を出さずにそのままゲームへ移ります(チラつき防止)。
スプラッシュは「アプリケーション」→「Boot Splash」の設定(画像/背景色/拡大/フィルタ)をそのまま反映します。指定が無ければ ACTION GAME MAKER 内蔵のスプラッシュになります。
ただし、起動時にオブジェクトプールの事前生成が残っている場合は、チラつき防止よりローディング画面の表示を優先します(事前生成の完了を待つ相手が必要なためです)。
連結スライド遷移では表示しません
シーン遷移エディタで連結スライド(SLIDE_UP_CONNECT など)を指定した遷移では、ローディング画面を表示しません。連結スライドは「隣の部屋へシームレスに移動する」ための演出で、ローディング画面を挟むと連結スライドとプレイヤーの移動演出がすべて隠れてしまうためです。
遷移前演出・遷移後演出のどちらかに連結スライドを指定していれば、表示しません。
オブジェクトプール
どういうときに効くか
オブジェクトを新しく作る処理には時間がかかります。1 体ずつなら気になりませんが、弾を 20 発同時に発射するようなまとめて作る場面では、そこだけフレームが落ちます。
オブジェクトプールは、その実体をローディング中に先に作っておき、消滅時も捨てずに休ませておいて次の生成で使い回す仕組みです。生成の待ち時間がなくなるので、まとめて出しても引っかかりません。
設定のしかた
- マップ制作ビューのレイヤードックで「マップ設定」の「+」を押し、「ゲームオブジェクトプール」を選びます。
- 「プールの一覧」に要素を追加します。
- 「オブジェクトパス」に、プール対象にしたいオブジェクトのシーンを指定します。
- 必要に応じて「事前に生成する数」などを調整します。
以上です。設定はこのノードだけで完結します。 オブジェクト側・弾データ側・ビジュアルスクリプト側に設定する項目はありません。一覧へ登録したオブジェクトは、どの生成経路からでもプール経由になります。
追加先はマップ設定の直下です(事前生成の計画がシーンの読み込み時点で行われるため、レイヤーの中には置きません)。
ゲームオブジェクトプールの設定項目
「プールの一覧」の 1 要素につき、次の項目があります。
| 項目 | 意味 | 既定値 |
|---|---|---|
| プールの表示名 | 一覧で見分けを付けるための名前。参照には使いません | 空 |
| オブジェクトパス | 生成元となるオブジェクトのシーン。このシーンがプールの識別子になります | 空 |
| 事前読み込みのみ行う | ロードだけ先に済ませ、プールは持たない | オフ |
| 事前に生成する数 | あらかじめ作っておく数 | 8 |
| 不足時に自動で追加生成する | 在庫が尽きたときに追加で作るか | オン |
「不足時に自動で追加生成する」をオフにすると、在庫が尽きた分は通常どおり新しく作られ、その個体はプールへ返却されません。エラーにはならず、プールを使う前と同じ挙動になるだけです。
事前生成はフレームをまたいで少しずつ行われます(1 フレームあたりの時間に上限を設けています)。まとめて作り切ってフレームが止まることはありません。進捗はローディング画面へ渡され、事前生成が終わるまでローディング画面は消えません。
ノードの置き場所
休眠中の在庫はこのノードが持っています。 そのため、ノードが破棄されると在庫も失われます。置き場所で挙動が変わります。
| 置き場所 | 挙動 |
|---|---|
| シーン遷移で破棄されない場所 | 在庫がシーンをまたいで残ります。遷移時は貸し出し中の分も返却されるので、遷移後もそのまま使えます |
| ゲームシーンの中 | 遷移でノードごと破棄され、在庫も失われます。遷移先のノードが改めて事前生成します |
在庫をシーンまたぎで使い回したい場合は、常駐させてください。 手軽な方法は自動読み込みです。ゲームオブジェクトプールを 1 つ置いただけのシーンを作り、プロジェクト設定の「グローバル」→「自動読み込み」に登録します。登録したノードはゲーム開始時に一度だけ作られ、シーン遷移では破棄されません。
別のマップからコピーして持ってくることもできます。 貼り付け先はマップ設定の直下になります。
実行時に生成されるゲームオブジェクトの子に置いてはいけません。 事前生成の計画はシーンの読み込み時点で済んでいる必要があるため、専用のノードとしてシーンへ直接置いてください。
事前読み込みのみ行う
「事前読み込みのみ行う」をオンにすると、ロードだけを先に済ませて、在庫は持ちません。
- 生成元シーンのロード後に 1 体だけ作って即座に捨てます。シーンとその素材はロード済みのまま残るので、実際に生成するときの引っかかりが減ります
- そのシーンのオブジェクトは通常どおり生成されます(プールから配られず、消滅時もそのまま消えます)
- ルートノードの型を問いません。 ゲームオブジェクト以外のシーンや、UI のシーンも登録できます
- 「事前に生成する数」「不足時に自動で追加生成する」は使わないため、編集できなくなります
「使い回しはしたくないが、出た瞬間の引っかかりは消したい」オブジェクトに向いています。
エフェクトとパーティクルはこの設定が効きます。 EffectObject / ParticleObject は使い回しの対象外(後述)ですが、「事前読み込みのみ行う」なら型を問わないので登録できます。初めて表示するときのロードを先に済ませられるため、初回の引っかかりが軽くなります。 使う予定のエフェクトをまとめて登録しておくとよいでしょう。
対象になるオブジェクト
使い回しの対象になるのは、ゲームオブジェクトと軽量オブジェクトだけです。 返却をこの 2 種類の消滅処理から行っているためです。
物理演算で動くオブジェクト(PhysicsGameObject)、エフェクト(EffectObject)、パーティクル(ParticleObject)、その他のノードは対象外です。これらは消滅時にプールへ返却する経路を持たないためです。「オブジェクトパス」には任意の .tscn を指定できてしまいますが、ルートが対象の種類でないシーンはプールが作られません(実行時にログで知らせます)。
「事前読み込みのみ行う」の場合はこの制限が掛かりません。 エフェクトやパーティクルは、こちらで登録して初回のロードだけ先に済ませてください。
効く生成経路
一覧へ登録すれば、下記のすべてが自動的にプール経由になります。 経路ごとの設定はありません。
| 経路 | 例 |
|---|---|
| 弾の発射 | 弾を撃つアクション |
| オブジェクトの生成 | 「オブジェクトを生成」アクション |
| 接続オブジェクト | 子として生成されるオブジェクト |
| オブジェクトの変更 | 「オブジェクトを変更」アクション |
| 復活 | 消滅したオブジェクトの復活、カメラ外からの復帰、シーン切り替え後の復元 |
返却されるタイミング
オブジェクトが消えるときに、削除の代わりにプールへ戻ります。 消滅アクション、オブジェクトの変更、シーン遷移のいずれでも返却されます。
戻ってきた個体は、返却の時点でシーンに保存されている状態へ戻されます。実行時に変わったプロパティは保存値へ、実行時に追加されたノードは削除、ビジュアルスクリプトは初期アクションから走り直す状態へ戻ります。取り出すときではなく戻すときに片付けるので、まとめて出す場面でコストが増えません。
シーンに最初から配置してあるオブジェクトは返却の対象外です(プールから配られたものではないため、そのまま削除されます)。
エディタの警告とログ
設定の取りこぼしは、シーンツリー上の警告で気付けます。
- 「オブジェクトパス」が未設定
- 「オブジェクトパス」が重複(同じシーンを複数登録すると、後ろ側は使われません)
実行時には、事前生成の失敗をログで知らせます(パス未設定/パスが解決できない/重複/ロード失敗/ルートが対象の種類でない)。
プールが無いこと自体はログに出ません。 一覧へ登録していないオブジェクトは通常生成されるだけで、設定ミスではないためです。
在庫が尽きただけの場合(「不足時に自動で追加生成する」がオフ)は、通常の生成へ回すだけなので何も出ません。
実用例
弾を 20 発同時に撃つとそこだけカクつく
- ゲームオブジェクトプールを置き、「オブジェクトパス」に弾のシーンを指定します。
- 「事前に生成する数」を、同時に画面に出る最大数より少し多めにします(20 発なら 24 など)。
- 弾データ側は何も変えずに実行します。
在庫が足りているかどうかは、「不足時に自動で追加生成する」をオフにして試すと分かります。足りていなければ途中の弾だけ引っかかるので、その分「事前に生成する数」を増やしてください。確認が済んだらオンへ戻しておくと、想定外の場面でも弾が出なくならずに済みます。
ローディング画面に「Now Loading」を出す
- マップ一覧の「+ 新規作成」→ 種類「ローディングシーン」で作ります。
この時点で、黒い背景・ゲージ・「NOW LOADING …」のラベル・点を増減させるアニメーションが入った状態になっています。あとは「設定」→「基本的な設定」で有効にし、プルダウンからこのシーンを選べば動きます。
見た目を変えたい場合は、レイヤードックの「+」から要素を足し、ラベルの文言やゲージの色を調整してください。消えるときの演出を自分で作る場合は、AnimationPlayer に hide という名前のアニメーションを追加します(ループはオフにしてください)。
ボスのシーンだけ先に読み込んでおく
使い回しはしたくないが、出現時の引っかかりを消したい場合です。
- ゲームオブジェクトプールの「プールの一覧」に要素を追加します。
- 「オブジェクトパス」にボスのシーンを指定します。
- 「事前読み込みのみ行う」をオンにします。
ボスは通常どおり生成されますが、シーンと素材はロード済みなので出現が軽くなります。
在庫をステージをまたいで使い回す
- ゲームオブジェクトプールを 1 つ置いただけのシーンを作り、
res://に保存します。 - プロジェクト設定の「グローバル」→「自動読み込み」でそのシーンを登録します。
- プールの設定はそのシーンのノードに並べます。
ゲーム開始時に一度だけ事前生成が走り、以降のシーン遷移では作り直されません。ステージごとに置く場合との違いは在庫が残るかどうかだけで、設定項目は同じです。
注意点
- 非同期ロードにオン/オフの設定はありません。 シーンの読み込みは常に裏側で進みます。設定が要るのはローディング画面とオブジェクトプールだけです。
- ローディングシーンの設定は「設定」→「基本的な設定」にあります。 プロジェクト設定から直接触る場合は「高度な設定」側(
application/loading_scene/*)なので、トグルをオンにするか検索欄にloadingと入れてください。 - ローディング画面のルートに
GameScene/MenuScene/CoreSceneは指定できません。 指定するとログにエラーが出て表示されません。 - ローディング画面にビジュアルスクリプトのキャラを置くなら、ルートを
LoadingSceneにしてください。 他の型では登録されず、置いても動きません。エラーも警告も出ないので気付きにくい箇所です。 hideアニメーションのループはオフにしてください。 ループしていると完了の通知が来ません。検出するとログで知らせ、暗幕での撤去に切り替えます。- 撤去が成立しないまま時間が経つと、強制的に撤去します。 何を待っていたかはログに出ます。事前生成の数が極端に多い場合もここで打ち切られますが、残りは取り出し時に作られるので動作に影響はありません。
- 進捗バーは 1 つだけ自動更新されます。 複数出したい場合はルートのスクリプトで
set_progressを受け取ってください。実装すると自動更新は止まります。 - 連結スライド遷移ではローディング画面が出ません。 遷移前・遷移後のどちらかに連結スライドを指定していれば表示しません(仕様です)。
- ゲームオブジェクトプールのノードが破棄されると在庫も失われます。 シーンまたぎで使い回したい場合は、自動読み込みなどで常駐させてください。
- 同じシーンを複数のプールに登録しないでください。 生成元シーンがプールの識別子なので、後ろ側は使われません。シーンツリーの警告で気付けます。
- プールの対象はゲームオブジェクトと軽量オブジェクトだけです。 それ以外を「オブジェクトパス」に指定してもプールは作られません(「事前読み込みのみ行う」を使う場合は型を問いません)。
- 在庫が尽きたときの挙動は静かです。 「不足時に自動で追加生成する」がオフだと通常生成へ回るだけで、ログも出ません。在庫が足りているかを確かめたいときは、意図的にオフにして試してください。
- 使い回しは「消えて戻った個体を作り直さない」だけです。 オブジェクトの状態は返却時にシーンの保存値へ戻されるので、前回の続きから始まることはありません。逆に、実行時に足した子ノードを次回も残したい、といった使い方はできません。
- 実行時に生成されるオブジェクトの子にゲームオブジェクトプールを置かないでください。 事前生成の計画がシーン読み込み時に済んでいる必要があります。
- オブジェクトプールが狙っているのは生成時間の削減です。メモリ使用量は事前生成した分だけ増えます。
- 事前生成の数はそのままローディング時間になります。 1 体あたりの生成時間はオブジェクトの規模によりますが、ビジュアルスクリプト付きの弾では数ミリ秒かかります。数百体にすると数秒単位で伸びるので、実際に同時に出る数を見て決めてください。