La base de un motor de videojuegos, son las físicas, los cálculos, la precisión, la forma de interactuar y entenderlas dentro del motor, pero como desarrolladores debemos saber usarlos con mesura y no excedernos.
Las físicas es una de las características que más consume cálculos al procesador en tiempo real, por eso NVidia ha apartado núcleos en la tarjeta gráfica que incluyen el cálculo de físicas.
Unity gestiona envíos de tareas de físicas al GPU a través del componente rigidbody, si su gráfica soporta CUDA, sino el cálculo se hace en el procesador en un núcleo diferente. Sin embargo debemos seguir desarrollando como si no contaramos con CUDA cores, porque no sabemos a que dispositivo de destino va nuestro juego, por eso a continuación daré algunas consideraciones.
Evita a toda costa los Mesh Collider.
El orden de uso del collider más barato al más costoso es: Sphere collider como el menos costoso, luego Capsule Collider, BoxCollider y por último Mesh Collider, lo mismo aplica a sus equivalentes en 2D. Si tienes formas muy complicadas trata de usar un conjunto de esferas, cápsulas y cajas, pero si por algún motivo la cuestión es de precisión, entonces debes hacer una malla de bajo poligonaje en tu programa habitual de modelado para ser lo más precisos pero consumiendo lo mínimo.
Evita a toda costa las colisiones grandes.
Supongamos que tienes un plano muy grande como suelo, una práctica que se repite mucho. Cuando tienes un jugador que pisa el suelo, no hay problema, y 5 enemigos tampoco hay problema, pero a medida que vas aumentando la cantidad de enemigos que pisan ese mismo plano como en el caso de un juego como una invasión Zombie, ahi si que se nota los problemas.
Cada objeto que usa un rigidbody y pisa el mismo plano, genera un montón de llamadas a las físicas de ese mismo suelo. Si requieres de un plano tan grande para físicas es mejor que uses un terrain, ya que la colisión del terrain gestiona mejor las físicas que un plano o un cubo, si aún quieres usar un cubo o un plano grandísimo, puedes usar varios cubos como físicas y desactive las colisiones que no están siendo usadas en el momento.
Físicas de cuerpos blandos.
Me refiero a las físicas como cabello o ropa, que hacen que nuestro juego luzca de manera impresionante, esto también tiene un costo muy elevado y a hoy día no he logrado hacer que corra bien. Hay 3 trucos:
El que definitivamente si te va a servir es que hagas simulación del cabello y la ropa dentro de tu programa de modelado y lo conviertas en animación, esta solución es un tanto creíble y no se nota casi.
Agregar huesos adicionales a los elementos como telas sueltas o cabellos sin animación y usar un Spring Joint en ese hueso, esta forma es más barata que usar Skin Cloth.
La última opción en teoría, porque no tengo manera de probarla es pintar la influencia del viento y el movimiento usando los colores de los vértices y hacer un shader que aproveche estos colores para simular movimiento, es una opción que es difícil de aplicar y solo le he visto aplicada a algunos shader que renderizan pelaje, como fur-shader y en shaders para vegetación, pero no es tan creíble y es casi como reinventar el Skin Cloth.
Si definitivamente vas a usar Skin Cloth, usa mallas más simples posibles y solo aplicalo sobre los personajes principales, nunca hagas esto en los enemigos o en los NPC, también puedes usar la pintura de los vértices y algun script que te ayude a posicionar las influencias en el skin Cloth.
Uso de ragdolls al mínimo.
Si quieres evitarte problemas desde el principio usa animaciones de muertes o caídas en vez de ragdolls, pero si deseas usar ragdolls, solo activarlo en el momento que lo necesites, dale un tiempo prudente para que el cadáver encuentre su punto de reposo y desactivarlo.
Usa Layers en vez de Tags.
Este se explica por sí solo, usar scripts que encuentren layers son más rápidos, en cambio usar tags cuesta un poco en rendimiento, la razón es que cualquier búsqueda que use una cadena de caracteres es más costosa porque tiene que comparar un array de caracteres con otro y esto toma su tiempo. en cambio las capas son solo 32 números fijos.
Usa pocas llamadas al ControllerColliderHit.
Si usas un Character controller usa lo menos posible este comando, trata de evitar este cálculo usando algún truco, que mejor uses un capsule Collider con un rigidbody bloqueando las rotaciones en X y Z.
Reduce las llamadas al comando CharacterController.Move(), el controlador de caracteres se produce de forma sincrónica y cada llamada puede tener un coste de rendimiento significativo, lo que hago es almacenar en memoria las solicitudes de movimiento por fotograma y aplicarlas sólo una vez.
Reducir el tiempo de Fixed Time.
Establecer la simulación de la física timestep al mínimo posible, por defecto FixedUpdate() se encuentra en 0.02 segundos y Update() en 0.33 segundos máximo, así que tienes que subir poco a poco el Fixed Time step para que más o menos a 16 milisegundos, todo depende de las máximas velocidades de las físicas para que no ocurra el efecto túnel y se traspasen los objetos entre sí.
Minimice el uso de Raycast.
El uso de comprobaciones de raycast y spherecast es costoso porque guarda un montón de datos, en lo posible use linecast que es un poco menos costoso o puede optar por usar Bounds.IntersectRay(), es aun mas barato pero es algo atípico, puede optar por usarlo para cosas que no sea calculo de fisicas.
Con esto concluimos los consejos de rendimiento en físicas, recuerde que no todo son físicas en tiempo real, puedes hacer uso de la creatividad para crear fuerzas o influencias a partir de aplicar un poco de geometría.
Comentarios