質問: ### 前提・実現したいこと Unity2Dでダークソウルのようなファストトラベル付きのシームレスマップを実装したい。 現在予定している仕様については以下で詳細を述べます。 しかしこの仕様に添って提案・アドバイスを行う必要は全くなく、他によい実装があればどうかご教授くださいませ。 よろしくお願いいたします。 ### 現在考えている仕様 ・まずゲーム全体を一つの大きなシーンにする。 ・ステージが5つとするなら5つはそれぞれマップにつき一つのTileMapオブジェクトと環境物、敵、ギミックなどで占められていると仮定する。 ・それに加えてそれぞれのマップをつなぐ通路的な小さな空間を用意する。 ・普段は現在いる一つのマップ以外の4つのオブジェクトは非アクティブにしておく。 ・マップの切れ目近くで次のマップのテクスチャなどのデータを非同期でロードし、マップに侵入する通路で次のマップのオブジェクトを全て一斉に(一部ずつにしたほうがいいでしょうか?)アクティブにする。 ・次のマップに入れば通路を除く前のマップは非アクティブにしてデータもアンロードする。 ・敵のステータスに所属マップを加えて休憩ポイントで休憩した際とファストトラベルした際に蘇る敵を管理する。 ・ギミックと敵はプレイヤーの近くに来るまで機能を停止していて、ある程度離れるとまた機能停止する。しかし初期位置?元の持ち場?というか縄張りを離れていた場合戻るまでは敵キャラは動く。(startメソッドで初期位置を記録する) というようなやり方でシームレスマップと敵キャラを管理したいと思うのですがいかがでしょうか? メモリ管理に自分なりに気を遣った結果ですが、至らぬ点、あるいは根本の方向性からして間違っているということがあればご指摘いただければ幸いです。 また足りない情報などあればお手数ですがご指摘くださいませ。 どうぞよろしくお願いいたします。 ### 追記 手前で色々と調べた結果、上の仕様に加えて ・マップをアクティブにした際環境物やエネミーなどのオブジェクトはコンポーネントのenableを切った状態にして呼び出す。 そして近くに入ったらenableをtrueにする。(この際スプライトレンダラーの方はそもそもカメラに入っていない場合は切らなくていいですか?) というのを加えてみることにしました。 色々と調べましたが正直あまり定まらず、僕が好きな2Dゲームでは(シームレスです)シーン移動のようなものはなく、あるマップのはしから落ちると別のマップの地面に叩きつけられるようなこともあったので一つのシーンにマップを集めていいのではないかと思い至った次第です。 それからUse By Compositeを使うかどうか悩んでいます。 デフォルトのタイルマップコライダーを無効化してコンポジットコライダーを利用するプロパティのようですが、 2D タイルマップアセットワークフロー 上記記事の記述によると最適化されるようなので今のところ使うつもりです。 そして上の仕様でプロファイラーを注視しつつ作っていきますがアドバイスがあればぜひとも教えて下さい。 よろしくお願いします。 ### さらに追記 マップそのものをプレハブ化して呼び出すアプローチを試してみる。 呼び出す際もインスタント化とオブジェクトプールの2つを試してみる。 ↓ インスタンス化ではフレームレートが低下し入力が遅延するなどゲームプレイを阻害し、メモリ使用量もかなり増えていた。 しかし前のマップを消すとメモリ使用量は改善されたが前に試した方法に比べて劇的に改善されているかというとそんなことはなかった。 オブジェクトプールについても検証してみる。 ↓ オブジェクトプールの方針で試してみましたが、こちらは非常にメモリ使用量が高くなりました。 フレームレートは安定して入力遅延は抑えられたものの良くない方法だと結論づけざるを得ないように感じます。 結果として最初のやり方が一番安定しているように思いました。 ↓ 最初のやり方の際には正直マップが小さかったです。 そのことを加味していなかったせいか改めて試すとこちらでもメモリ使用量が大きいです。 ManagedHeapが大きいのでそもそもコードに問題がある可能性が大きいです。 しばらく色々と軽量化してみます......。 ↓ フレームレートが落ちている際もcpu、gpuの使用率は共に20%を上回らないようです。 パソコンの設定のせいなのかこれでは本当の負荷が測れていない可能性がありそうな気がする。
回答: 様々な検討を重ねた結果以下のような方法に落ち着きました ・ゲーム全体を一つの大きなシーンにする。 ・ステージが5つとするなら5つはそれぞれステージを複数に分割したいくつかのTileMapオブジェクトと環境物、敵、ギミックなどで占められていると仮定する。 これらの要素を含むステージを分割した欠片を以下ではひとかたまりでマップパーツと呼ぶ。 ・ステージに加えてそれぞれのステージをつなぐ通路的な小さなマップがあるとする。 ・この通路ではテクスチャデータなどのロード、アンロードを行う。 ・マップパーツはプレハブにしておいて、普段は現在地点周囲のマップパーツのみをインスタンス化する。不要になれば破棄する。 ・マップパーツとマップパーツの継ぎ目にオブジェクトを配置し、プレイヤーがそのオブジェクトに右から触れたか左から触れたかでトリガーイベントを発生させて進行方向の先にあるマップをインスタンス化する。 ・この触れるという判定はカメラサイズの3倍ほどの大きさのトリガー判定をプレイヤーにつけて行う。 ・また一度生成されたマップはしばらくは消えない。マップパーツの切れ目で行き来することにより何度も生成したり破棄したりするのを避けるため。 ・敵のステータスに所属ステージをつけて休憩ポイントで休憩した際とファストトラベルした際に蘇る敵を管理する。 ・ギミックと敵はプレイヤーの近くに来るまで機能を停止していて、ある程度離れるとまた機能停止する。しかし元の持ち場?というか縄張りを離れていた場合戻るまでは敵キャラは動く。 自己解決が遅くなりまして大変申し訳ありません。 どなたかの参考になれば幸いです。