¿Qué estás buscando?
Hero background image
Rendimiento físico mejorado para una mayor fluidez de juego

Este es el quinto de una serie de artículos que desgrana consejos de optimización para tus proyectos Unity. Utilízalos como guía para correr a mayor velocidad de fotogramas con menos recursos. Una vez que hayas probado estas buenas prácticas, no dejes de consultar las demás páginas de la serie:

La física puede crear una jugabilidad intrincada, pero esto tiene un coste de rendimiento. Una vez que conozca estos costes, podrá ajustar la simulación para gestionarlos adecuadamente. Utilice estos consejos para mantenerse dentro de su objetivo de velocidad de fotogramas y crear una reproducción suave con la Física incorporada de Unity (NVIDIA PhysX).

Interfaz de opciones de cocina en el editor de Unity
Compruebe sus colisionadores

Las mallas utilizadas en física pasan por un proceso llamado Cocción. Esto prepara la malla para que pueda trabajar con consultas de física como emisiones de rayos, contactos, etc.

Un MeshCollider tiene varias CookingOptions para ayudarte a validar la malla para la física. Si está seguro de que su malla no necesita estas comprobaciones, puede desactivarlas para acelerar el tiempo de cocción.

En las CookingOptions de cada MeshCollider, desmarca las opciones EnableMeshCleaning, WeldColocatedVertices y CookForFasterSimulation. Estas opciones son valiosas para las mallas generadas proceduralmente en tiempo de ejecución, pero pueden desactivarse si tus mallas ya tienen los triángulos adecuados.

Si te diriges específicamente a PC, asegúrate de mantener activada la opción Usar fase intermedia rápida. Esto cambia a un algoritmo más rápido de PhysX 4.1 durante la fase media de la simulación (que ayuda a reducir un pequeño conjunto de triángulos potencialmente intersecantes para las consultas de física). Las plataformas que no son de sobremesa deben seguir utilizando el algoritmo más lento que genera árboles R.

Los colisionadores de malla suelen ser caros, así que considera sustituir los colisionadores de malla más complejos por otros primitivos o simplificados para aproximarte a la forma original.

Más información en la documentación de CookingOptions.

Interfaz BakeMeshJob
Utilizar Physics.BakeMesh

Si estás generando mallas proceduralmente durante el juego, puedes crear un Mesh Collider en tiempo de ejecución. Añadir un componente Mesh Collider directamente a la malla, sin embargo, cocina la física en el hilo principal. Esto puede consumir mucho tiempo de CPU.

Utilice Physics.BakeMesh para preparar una malla para su uso con un Mesh Collider, y guardar los datos baked con la propia malla. Un nuevo Mesh Collider que haga referencia a esta malla reutilizará estos datos precalentados, en lugar de calentar la malla de nuevo. Esto puede ayudar a reducir el tiempo de carga de la escena o el tiempo de instanciación posterior. Para optimizar el rendimiento, puede descargar la cocción de la malla a otro hilo con la función Sistema de trabajos de C.

Consulte este ejemplo para obtener más información sobre cómo bakear mallas en varios subprocesos.

Interfaz de configuración del proyecto de Física
Ajuste su configuración

En la Configuración del reproductor, marque Prebake Collision Meshes siempre que sea posible. También recomendamos revisar la configuración de la matriz de colisión para asegurarse de que el jugador y los objetos mecánicos del juego están en las capas correctas.

La eliminación de las devoluciones de llamada de los disparadores de capas innecesarias puede ser una gran victoria, así que trate de simplificar su Matriz de Colisión de Capas. Puede editar su configuración de física a través de Configuración del proyecto > Física.

Más información en la documentación Matriz de colisiones.

Paso de tiempo fijo por defecto en el editor de Unity
Modificar la frecuencia de simulación

Los motores de física funcionan con un intervalo de tiempo fijo. Para ver la tasa fija a la que está funcionando su proyecto, vaya a Editar > Configuración del proyecto > Tiempo.

El campo Fixed Timestep define el delta de tiempo utilizado por cada Physics Step. Por ejemplo, el valor predeterminado de 0,02 segundos (20 ms) equivale a 50 fotogramas por segundo (fps), o 50 Hz.

Dado que cada fotograma en Unity tarda una cantidad variable de tiempo, no está perfectamente sincronizado con la simulación física. El motor cuenta hasta el siguiente Timestep de física. Si un cuadro corre ligeramente más lento o más rápido, Unity usa el tiempo transcurrido para saber cuando correr la simulación de física en el Timestep apropiado.

Si un fotograma tarda mucho en prepararse, pueden producirse problemas de rendimiento. Así que si tu juego experimenta un pico (por ejemplo, instanciando muchos GameObjects o cargando un archivo desde el disco), el fotograma podría tardar 40 ms o más en ejecutarse. Con el Timestep fijo de 20 ms por defecto, esto provocaría que se ejecutaran dos simulaciones físicas en el fotograma siguiente para "ponerse al día" con el Timestep variable.

Las simulaciones físicas adicionales, a su vez, añaden más tiempo para procesar el fotograma. En plataformas de gama baja, esto puede llevar a una espiral descendente del rendimiento.

Si se tarda más en preparar un fotograma posterior, también se alarga la acumulación de simulaciones físicas. Esto hace que los fotogramas sean aún más lentos y haya que ejecutar más simulaciones por fotograma. El resultado es un rendimiento debilitado.

Eventualmente, el tiempo entre actualizaciones de física podría exceder el Timestep Máximo Permitido. Después de este corte, Unity empieza a dejar de actualizar la física, y el juego tartamudea.

Para evitar problemas de rendimiento con la física:

  • Reduce la frecuencia de simulación: Para plataformas de gama baja, aumente la Frecuencia de cuadro fija a un valor ligeramente superior a la frecuencia de cuadro objetivo. Por ejemplo, utilice 0,035 segundos para 30 fps en móvil. Esto podría ayudar a evitar esa espiral descendente de rendimiento.
  • Disminuir la Temporización Máxima Permitida: Usando un valor más pequeño (como 0.1 segundos) sacrificará algo de precisión en la simulación física, pero también limitará cuántas actualizaciones físicas pueden tener lugar en un fotograma. Experimenta con los valores hasta encontrar algo que se adapte a los requisitos de tu proyecto.
  • Simule manualmente el Paso de Física si es necesario: Desactiva la opción Auto Simulación en los Ajustes de Física, e invoca directamente Physics.Simulate durante la fase de Actualización del fotograma. Esto le permite determinar activamente cuándo ejecutar el Paso de Física. Pasa Time.deltaTime a Physics.Simulatepara mantener la física sincronizada con el tiempo de simulación.
  • *NOTA*: Este enfoque puede provocar inestabilidades en la simulación física, especialmente en escenas con una física compleja o tiempos de fotograma muy variables. Utilízalo con precaución.

Más información en la documentación de Physics.Simulate.

Interfaz de Broadphase Type
Utilice la poda en cajas para escenas grandes

El motor de física de Unity funciona en dos pasos:

  • La fase amplia: Recoge las posibles colisiones mediante un algoritmo de barrido y poda.
  • La fase estrecha: Cuando el motor realmente calcula las colisiones

La configuración por defecto de fase amplia de Barrido y Prune Broadphase(Editar > Configuración del proyecto > Física > Tipo de fase amplia) puede generar falsos positivos para mundos que son generalmente planos, y tienen muchos colisionadores. Si su escena es grande y mayoritariamente plana, evite este problema y cambie a la Poda Automática de Cajas o a la Poda Multicajas Broadphase. Estas opciones dividen el mundo en una cuadrícula, donde cada celda de la cuadrícula realiza Barrido y Poda.

Multibox Pruning Broadphase le permite especificar manualmente los límites del mundo y el número de celdas de la cuadrícula, mientras que Automatic Box Pruning lo calcula todo por usted.

Consulte aquí la lista completa de propiedades de Physics.

Iteraciones del solucionador predeterminado
Modificar las iteraciones del solucionador

Si desea simular un cuerpo físico específico con mayor precisión, aumente sus Rigidbody.solverIterations. Esto anula el Physics.defaultSolverIterations, que se puede encontrar a través de Edit > Project Settings > Physics > Default Solver Iterations.

Para optimizar sus simulaciones físicas, establezca un valor relativamente bajo en el defaultSolveIterations del proyecto. A continuación, aplique valores de Rigidbody.solverIterations personalizados más altos a las instancias individuales que necesiten más detalles.

Más información sobre Rigidbody.solverIterations.

Sincronización automática desactivada en una escena
Desactivar la sincronización automática de transformaciones

Cuando usted actualiza un Transform, Unity no lo sincroniza automáticamente con el motor de física. Unity acumula transformaciones y espera a que se ejecute la actualización de la física o a que el usuario llame a Physics.SyncTransforms.

Si quieres sincronizar la física con tus Transforms con más frecuencia, puedes configurar Physics.autoSyncTransform a True (también se encuentra en Project Settings > Physics > Auto Sync Transforms). Cuando esto está habilitado, cualquier Rigidbody o Collider en ese Transform, junto con sus hijos, se actualizan automáticamente con el Transform.

Sin embargo, si no es absolutamente necesario, desactívelo. Una serie de consultas físicas sucesivas (como las emisiones de rayos) puede provocar una pérdida de rendimiento.

Más información sobre Physics.SyncTransforms.

Única instancia de colisión
Reutilización de las llamadas de colisión

Eventos de colisión y disparo (OnCollisionEnter, OnCollisionStay, OnCollisionExit, OnTriggerEnter, OnTriggerStay, OnTriggerExit) se dispararán para cualquier MonoBehaviour que implemente estas funciones y cumpla los criterios de interacción. Estos eventos también se enviarán a los MonoConductores desactivados.

Por eso se recomienda implementar estas funciones sólo cuando sea necesario, ya que se llamará a funciones vacías no esenciales. Se debe tener especial cuidado con OnCollisionStay y OnTriggerStay porque estos pueden ser llamados múltiples veces dependiendo del número de colliders involucrados.

Las llamadas de retornoMonoBehaviour.OnCollisionEnter, MonoBehaviour.OnCollisionStayy MonoComportamiento.OnColisiónSalir también toman una instancia de colisión como parámetro. Esta instancia de colisión se asigna en el montón gestionado y debe ser recogida de la basura.

Para reducir la cantidad de basura generada, active Physics.reuseCollisionCallbacks(que se encuentra en Configuración del proyecto > Física > Reutilizar Collision Callbacks). Con esto activo, Unity solo asigna una instancia de par de colisión a cada callback. Esto reduce los residuos para el recolector de basura (GC) y mejora el rendimiento general.

*NOTA*: Si hace referencia a la instancia de colisión fuera de los Collision Callbacks para el post-procesamiento, debe desactivarReuse Collision Callbacks.

Más información sobre Physics.reuseCollisionCallbacks.

Mover los colisionadores estáticos

Los Static Colliders son GameObjects con un componente Collider pero sin un Rigidbody. Contrariamente a su nombre, puedes mover un Colisionador Estático.

Simplemente modifique la posición del cuerpo físico, acumule los cambios posicionales y sincronice antes de la actualización de la física.No necesita agregar un componente Rigidbody al Static Collider solo para moverlo. Pero si quieres que el Static Collider interactúe con otros cuerpos físicos de una manera más compleja, dale un cuerpo rígido cinemático. Utilice Rigidbody.position y Cuerpo rígido.rotación para moverlo en lugar de acceder al componente Transformar. Esto garantiza un comportamiento más predecible del motor de física.

*NOTA*: En física 2D, no muevas los Colisionadores Estáticos porque la reconstrucción del árbol consume mucho tiempo.

Más información sobre Cuerpos rígidos.

Utilizar consultas sin asignación

Para detectar y recoger colisionadores dentro de una cierta distancia, en una dirección particular, utilice raycasts y otras consultas de física como BoxCast.

Consultas de física que devuelven varios colisionadores en forma de matriz, como SuperposiciónEsfera o OverlapBoxnecesitan asignar esos objetos en el montón gestionado. Esto significa que el recolector de basura eventualmente necesita recoger los objetos asignados, lo que puede disminuir el rendimiento si ocurre en el momento equivocado.

Para reducir esta sobrecarga, utilice las versiones NonAlloc de esas consultas. Por ejemplo, si está utilizando OverlapSphere para recoger todos los posibles colisionadores alrededor de un punto, asegúrese de utilizar OverlapSphereNonAlloc. Esto te permite pasar un array de colliders (el parámetro results) para que actúe como un buffer.

El método NonAlloc funciona sin generar basura. En caso contrario, funciona como el método de asignación correspondiente. Sólo recuerde definir un búfer de resultados de tamaño suficiente cuando utilice un método NonAlloc. El búfer no crece si se queda sin espacio.

Más información en la documentación del método NonAlloc.

Consultas por lotes para raycasting

Aunque puede ejecutar consultas raycast con Física.Raycastpuede requerir una cantidad significativa de tiempo de CPU. Esto es especialmente cierto si tiene un gran número de operaciones de raycast (por ejemplo, calcular la línea de visión para 10.000 agentes).

Utilice RaycastCommand para realizar la consulta por lotes utilizando el sistema de trabajos de C#. Esto descarga de trabajo al hilo principal para que las emisiones de rayos puedan producirse de forma asíncrona y en paralelo.

Vea un ejemplo en la documentación de RaycastCommands.

Interfaz del depurador de física
Visualizar con el depurador de física

Utilice la ventana Depuración de lafísica (Ventana > Análisis > Depurador de la física) para ayudar a solucionar cualquier colisionador problemático o discrepancia. Esta ventana muestra un indicador codificado por colores de los GameObjects que pueden colisionar entre sí.

Para más información, consulte la página de visualización Physics Debug.

clave de unidad art 21 11
Obtenga el libro electrónico gratuito

Una de nuestras guías más completas reúne más de 80 consejos prácticos sobre cómo optimizar tus juegos para PC y consola. Creados por nuestros expertos ingenieros de Success y Accelerate Solutions, estos consejos en profundidad te ayudarán a sacar el máximo partido de Unity y a aumentar el rendimiento de tu juego.

¿Te gustó este contenido?