新しいオブジェクトを即座にインスタンス化するのではなく、オブジェクトプールの作成と使用を常に検討する必要があるのはなぜですか?


25

このパターンについて何度か読みました(ベストプラクティスの観点から)。

メモリ割り当て:新しいオブジェクトを即座にインスタンス化する代わりに、オブジェクトプールの作成と使用を常に検討してください。メモリの断片化を減らし、ガベージコレクタの動作を減らすのに役立ちます。

ただし、実際に何を意味するのかわかりません。どうすれば実装できますか?

たとえば、Unity GameObjectInstantiateメソッドを使用してをインスタンス化できますか?

Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity);

この使用は推奨されませんか?他に何を意味できますか?



おかげHellium私は(大きすぎる)指定されたビデオを見ていなかったが、テキストは本当に私が「インスタンス化と破壊の行為は非効率的であり、あなたのプロジェクトを遅くすることができ、」理解するのに役立ち
ムハンマドFaizanカーン

1
このアドバイスは一般的ですが、すべてのゲームに絶対的な要件ではないことに注意してください。特に、小さい/短いデスクトップゲーム、ジャムの提出、またはプロトタイプを作成している場合は、プーリングを実装するために邪魔になる必要はありません。私の浸漬テストでは、Unityは私たちがクレジットを与えるよりも優れた大規模な産卵と破壊に耐えます。;)しかし、ガベージを積み上げて後で収集するときにスタッターを発生させたくない長いゲームを作成している場合や、パフォーマンスへの影響がより強く感じられるモバイルプラットフォームをターゲットにしている場合は、プーリングを検討してください。
DMGregory

ありがとう@DMGregoryあなたは正しい。入力は常に貴重です。小さなゲームではオブジェクトのプーリングについて心配するべきではありません。コーディングに余分な作業が必要になるからです。
ムハンマドファイザンカーン

1
これは非常に一般的なパターンですが、「最初にプロファイルを作成し、次に最適化する」というルールで調整してください。重要ではないものを簡単に最適化できます。
コートアンモン-復活モニカ

回答:


41

同じプレハブの多くのインスタンスをインスタンス化することを計画している場合は、オブジェクトプーリングの使用を検討する必要があります。UnityのInstantiate関数を呼び出すことは、最も負担の大きいメソッド呼び出しの1つです。

オブジェクトプーリングとは、プレハブを使用する前にインスタンス化することです。インスタンス化するとすぐに非アクティブ化され、必要な場合にのみ再アクティブ化されます。これによりメモリ使用量は増加しますが、ゲームプレイ中にインスタンス化するCPUオーバーヘッドが回避されます。

たとえば、私は現在、実行時に数百の弾丸を生成する必要がある弾丸地獄ゲームに取り組んでいます。私は当初、オブジェクトプーリングなしでゲームを作成しようとしましたが、それは災害(2 fps未満)になりました。今、私はゲームが始まる前に500個の弾丸をプールし、ゲームは驚くほど高速(200 fps)で実行されます。

オブジェクトプーリングを使用できない状況があります。たとえば、プレイヤーの入力がどのプレハブが生成されるかを指示するゲームがある場合、通常のInstantiate呼び出しを使用する以外に選択肢がない場合があります。オブジェクトプーリングは、必要なオブジェクトが事前にわかっている場合にのみ可能です。

Sebastian LagueのYouTubeチュートリアルは、オブジェクトプーリングについて学ぶための素晴らしいリソースです:https : //youtu.be/LhqP3EghQ-Q


「インスタンス化と破壊の行為は非効率的であり、プロジェクトの速度を低下させる可能性があります。」という訳だ?つまり、もう少しコーディングする必要があることを意味します(非アクティブ化を有効にしたり、弾丸の位置を再度設定して、再度発砲できるようにする)
ムハンマドファイザンカーン

12
繰り返しのインスタンス化と破壊のコストの主な原因として、割り当てとガベージコレクションに言及する価値があります。十分なガベージを生成すると、最終的にはゲーム全体がガベージコレクターが一掃するのを待つ必要があります。;)
DMGregory

3
@corsiKaは80年代の最適化になります。Unityは問題のプレハブを非アクティブ化するだけで、システムに無視させることができます。
コンガスボン

2
「たとえば、プレイヤーの入力がプレハブの生成を指示するゲームがある場合、通常のInstantiate呼び出しを使用する以外に選択肢がない場合があります。」- あんまり。起動時(またはシーンの読み込み時)に必要なサイズに割り当てられた異なるプレハブの複数のオブジェクトプールを簡単に作成できます。または、作成したい場合は、複数のプレハブタイプを格納するオブジェクトプールも機能します。
イーサンビアライン

1
@DMGregory典型的なGC環境では、割り当て解除がほとんどのコストです。一般的な非GC環境では、割り当てがほとんどのコストになります。オブジェクトプーリングは両方に最適で、ほとんどの場合、同じコインの両面にすぎません。極端な場合、以前のゲームは、すべてのオブジェクトがget-goから「割り当てられた」状態で記述されていました-ゲームの実行中にメモリの解放/割り当てがほとんどまたはまったくありませんでした。何らかの方法で「プール」されていないものは、実際には使用していません。Unityは多くのリアルタイムの「メタデータ」を使用するため、プーリングはかなり役立つ可能性がありますが、実装が難しい場合もあります。
ルアーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.