¿Por qué debería considerar siempre crear y usar grupos de objetos en lugar de crear instancias del nuevo objeto sobre la marcha?

25

He leído sobre este patrón varias veces (desde una perspectiva de mejores prácticas):

Asignación de memoria : en lugar de crear instancias del nuevo objeto sobre la marcha, siempre considere crear y usar grupos de objetos. Ayudará a reducir la fragmentación de la memoria y hará que el recolector de basura trabaje menos.

Sin embargo, no sé lo que realmente significa. ¿Cómo puedo implementarlo?

Por ejemplo, ¿puedo crear una instancia GameObjectusando el Instantiatemétodo de Unity?

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

¿Se desaconseja este uso? ¿Qué más puede significar?

Muhammad Faizan Khan
fuente
Gracias Hellium. No vi el video dado (demasiado grande) pero el texto realmente me ayudó a entender "El acto de crear instancias y destruir es ineficiente y puede retrasar tus proyectos"
Muhammad Faizan Khan
1
Tenga en cuenta que si bien este consejo es común, no es un requisito absoluto para cada juego. Especialmente si está haciendo un juego de escritorio pequeño / corto, envío de jam o prototipo, no necesita salir de su camino para implementar la agrupación. En mis pruebas de remojo, Unity soporta incluso el desove masivo y la destrucción mejor de lo que le damos crédito. ;) Pero considere agrupar si está haciendo un juego largo en el que no desea que la basura se acumule y cause un tartamudeo cuando se recolecta más tarde, o si está apuntando a plataformas móviles donde cualquier impacto en el rendimiento se siente con mayor intensidad.
DMGregory
Gracias @DMGregory Tienes razón. su entrada siempre es valiosa. No debemos preocuparnos por la agrupación de objetos en juegos pequeños, ya que requerirá un trabajo adicional en la codificación.
Muhammad Faizan Khan
1
Este es un patrón muy común, pero asegúrese de moderarlo con la regla: "Primero perfile, luego optimice". Es fácil optimizar cosas que no importan.
Cort Ammon - Restablece a Monica el

Respuestas:

41

Si planea crear una instancia de muchas instancias del mismo prefabricado, definitivamente debería pensar en usar la agrupación de objetos. La función Instantiate de Calling Unity es una de las llamadas de método más exigentes que puede realizar.

La agrupación de objetos es cuando crea instancias de prefabricados antes de usarlos. Se desactivan inmediatamente después de la creación de instancias y se reactivan solo cuando se necesitan. Si bien esto aumenta el uso de memoria, evita la sobrecarga de la CPU de crear instancias durante el juego.

Por ejemplo, actualmente estoy trabajando en un juego de infierno de balas que requiere que se generen cientos de balas en tiempo de ejecución. Inicialmente intenté hacer el juego sin agrupar objetos, pero eso terminó siendo un desastre (menos de 2 fps). Ahora, reúno 500 balas antes de que comience el juego y el juego se ejecuta sorprendentemente rápido (200 fps).

Hay situaciones en las que no se puede usar la agrupación de objetos. Por ejemplo, si tiene un juego en el que la entrada del jugador dicta qué prefabricación se genera, entonces es posible que no tenga más remedio que usar la llamada de instanciación normal. La agrupación de objetos solo es posible cuando se sabe de antemano qué objetos se necesitarán.

El tutorial de YouTube de Sebastian Lague es un gran recurso para aprender sobre la agrupación de objetos: https://youtu.be/LhqP3EghQ-Q

Kevin H.
fuente
"El acto de crear instancias y destruir es ineficiente y puede ralentizar sus proyectos". ¿esta es la razón? Por lo tanto, significa que tenemos que codificar un poco más (como activar la desactivación o establecer nuevamente la posición de la bala para que podamos disparar nuevamente)
Muhammad Faizan Khan
12
Vale la pena mencionar la asignación y la recolección de basura como los principales contribuyentes al costo de repetición de instancias y destrucción. Genera suficiente basura y eventualmente todo el juego tiene que esperar a que el recolector de basura lo barra todo. ;)
DMGregory
3
@corsiKa sería una optimización de la era de los 80. Unity puede simplemente desactivar los prefabricados en cuestión, haciendo que sus sistemas lo ignoren.
congusbongus
2
"Por ejemplo, si tienes un juego en el que la entrada del jugador dicta qué prefabricación se genera, entonces es posible que no tengas más remedio que usar la llamada de instanciación normal". - Realmente no. Podría tener fácilmente múltiples grupos de objetos para diferentes prefabricados asignados a los tamaños deseados al inicio (o carga de escena). O, si uno quisiera hacerlo, también podría funcionar un grupo de objetos que almacena múltiples tipos prefabricados.
Ethan Bierlein
1
@DMGregory En un entorno típico de GC, la desasignación es la mayor parte del costo; En un entorno típico no GC, la asignación es la mayor parte del costo. La agrupación de objetos funciona muy bien para ambos, en realidad son solo dos caras de la misma moneda en su mayor parte. En el caso extremo, los juegos antiguos solían escribirse con todos los objetos "asignados" desde el principio: muy poca o ninguna memoria / asignación de memoria mientras el juego se estaba ejecutando. Realmente no usaste nada que no estuviera "agrupado" de alguna manera. Dado que Unity utiliza muchos "metadatos" en tiempo real, la agrupación puede ayudar bastante, aunque también puede ser más difícil de implementar.
Luaan