FISICAS: CONCEPTOS BASICOS (II)



Veíamos en la entrada anterior que un collider vendría a ser meramente un caparazón que le añadimos a una malla para que pueda colisionar con otras mallas, pudiendo ese caparazón tener la misma forma que la malla (mesh collider) o una forma que nosotros le diseñemos para él a partir de una o varias formas primitivas (primitive collider)que Unity nos ofrece.

Supongamos entonces que tenemos dos mallas en nuestra escena, a cada una de las cuales le asignamos un collider (del tipo que sea, eso no importa para este ejemplo). A través de un script vinculado a una de las mallas movemos su transform para que colisione contra la otra malla. Probadlo si queréis con dos cubos (que ya traen "de serie" un collider primitivo (obviamente, un box collider)). Comprobaréis que pese a tener cada malla un collider, a efectos prácticos es como si no lo tuvieran, ya que se atraviesan.

Esto sucede porque para que dos mallas puedan colisionar, además de estar ambas dotadas de su pertinente collider, es preciso que al menos una de las dos mallas tenga vinculado además un Rigidbody no kinemático.

Olvidémonos de momento del palabro "kinemático" y centrémonos en el Rigidbody.

Un rigidbody es el conjunto de datos que permiten a Unity calcular, entre otras cosas, las consecuencias que tendrá una colisión para el gameobject al cual se asigna dicho rigidbody.

Al igual que nos pasaría a nosotros si estuviéramos en clase de física, para que Unity calcule las consecuencias de una hipotética colisión necesita tener en cuenta factores como la masa del gameobject al que se vincula, la velocidad relativa a que se produce la colisión, si existe o no rozamiento y en qué medida, si hay o no gravedad, etc. Por resumir, asignando un rigidbody a un gameobject automáticamente estamos dotando a dicho gameobject de una serie de propiedades físicas, tales como gravedad, rozamiento y peso, ya que sin saber la masa de un objeto - por ejemplo- es imposible calcular el resultado de una colisión (probad si no a patear de manera indiscriminada objetos con diferentes masas, paredes de carga y yorkshires inclusive, para que comprobéis las diferentes posibilidades de desplazamiento).

Lo más impactante para los recién llegados a Unity cuando le asignamos un rigidbody a una malla -como muchos ya habréis comprobado- es que automáticamente, salvo que el suelo a su vez tenga otro collider, nuestra malla se pierde en las profundidades de la escena. Por eso se tiende por algunos (manuales de pago incluidos) a simplificar en ocasiones cuando se explica lo que es un rigidbody, limitándolo a "lo que hace que un objeto se vea afectado por la gravedad".

Y por ahí suelen empezar también las confusiones entre colliders y rigidbodies, debido a que los dos tienden a solaparse y es difícil explicar uno sin mencionar al otro. Es verdad que ambos son necesarios para que se produzca una colisión, pero intervienen en apartados distintos: el collider sería el dónde (se produce la colisión) y el rigidbody el cómo.

Supongo que se entiende que no tendría sentido asignar un rigidbody a una malla que no tenga un collider, ya que de nada sirve calcular una colisión que nunca tendrá lugar (ya que no hay collider para esa malla con el que colisionar o ser colisionado)

Sí cabe pensar en un collider que no tenga rigidbody. De hecho, es lo que en Unity se conoce como "static colliders".

Un collider estático, como su nombre indica, está pensado para objetos que no se van a mover en la escena. Este tipo de colliders sin rigidbody pueden interactuar/colisionar con otros colliders siempre que éstos colliders sí tengan vinculado un rigidbody (ya hemos visto que si ninguno de los dos objetos tiene un rigidbody la colisión no se produce, básicamente porque Unity no tiene ninguna forma de calcular las consecuencias de dicha colisión entre dos objetos "no físicos" y directamente obvia la colisión).

Lo que sucede es que cuando un collider dinámico (con rigidbody) se mueve y fruto de ese movimiento colisiona con un collider estático (sin rigidbody), como Unity ignora las propiedades físicas del collider estático, meramente éste -haciendo honor a su nombre- no se moverá. Y de hecho, si se moviera, y precisamente por lo expuesto (Unity no sabe calcular cómo y cuánto se ha de mover) el costo computacional sería brutal.

Por todo lo anterior, los static colliders son óptimos para las partes fijas de nuestro juego, tal como paredes, librerías, árboles y objetos similares que no han de moverse pero que tampoco han de atravesarse por los personajes y demás partes móviles del juego.

Espero que estos conceptos que estoy intentando explicar a cuentagotas queden claros. Sé que al principio parece todo un poco confuso, pero es esencial entenderlos correctamente.

Un abrazo y hasta pronto.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 11 Comments

FISICAS: CONCEPTOS BASICOS



Examinadas las clases principales de Unity, quisiera ahora realizar una serie de incursiones más o menos extensivas en algunos aspectos del engine que creo que merecen una atención especial, bien por su importancia, bien por la dificultad para entenderlos. Así que, avisando de nuevo en que este que os está escribiendo no es en absoluto un experto en la materia, intentaré ayudar en lo que buenamente pueda.

Quisiera empezar con un acercamiento a todo el componente de físicas del engine, que considero que es el centro neurálgico del noventa y pico por ciento de los videojuegos que se han creado.

Existe entre los recién llegados a Unity bastante confusión entre los términos y conceptos que envuelven su apartado de físicas, y en consecuencia a veces no se aplican correctamente los elementos necesarios para –por ejemplo- detectar adecuadamente una colisión o permitir que un determinado gameobject sea inmune a la gravedad. Para que nuestro juego funcione adecuadamente y no consuma más recursos de los necesarios debemos tener muy claro cuál es la mejor solución para cada necesidad.

Vamos a intentar desgranar para qué sirve cada cosa. Empezaremos por examinar las diferentes posibilidades de detección de colisiones que nos brinda Unity, y para ello necesitaremos introducir el primer concepto:

COLLIDER:

Un collider, en términos muy básicos, es un envoltorio que hace que un determinado objeto se torne sólido y en consecuencia pueda chocar con otros objetos (siempre que a su vez esos otros objetos tengan otro collider). Un collider se compone, por un lado, de una determinada forma (que no tiene por qué coincidir con la forma del objeto, aunque es preferible que “casen” de alguna manera, para originar colisiones creíbles) y, por otro, de un determinado material físico (aquí no estamos hablando de colores o modos de reflejar la luz de una superficie, sino de capacidad de rebote y/o fricción de dicho objeto, así que no confundamos el término “material” que usamos para renderizar un objeto con el material físico).

Atendiendo a su forma, podemos diferenciar los colliders en dos subgrupos: colliders de malla (mesh colliders) y colliders de primitivas (primitive colliders):

El mesh collider lo creamos cuando importamos una malla desde alguna aplicación 3d tipo Blender o 3dMax. Al seleccionar dicha malla desde la vista de Proyecto y previo a importarlo, debemos (caso de querer este tipo de malla) marcar la casilla “generate colliders” (ver captura de pantalla) para que nuestra malla tenga un collider de este tipo.



Cuando marcamos esta casilla e importamos la malla, Unity genera un collider que tendrá la misma forma que dicha malla (de ahí el nombre). Podríamos pensar: “pues ya está, es tan sencillo como pedir a Unity que genere colliders para todas las mallas que vayamos importando y ya tenemos nuestro sistema de detección de colisiones montado, sin necesidad de complicarnos la vida asignando colliders de primitivas que además no cuadran tan perfectamente con nuestras mallas como los colliders de malla”.

Pero no es tan sencillo. Para empezar, dos colliders de malla no colisionarán entre sí si al menos uno de ellos no tiene marcado en el inspector el checkbox “convex”, que hace que el collider envuelva adecuadamente la malla.

“No hay problema” –podemos pensar- “marco la casilla convex y asunto solucionado”.

Sigue sin ser tan sencillo. Si dos colliders de malla colisionan entre sí a una velocidad importante es posible que no se detecte la colisión.

“¿y para el caso de objetos que sé positivamente que no se moverán a mucha velocidad puedo usar mesh colliders?”

La respuesta es: poder, se puede, pero si se puede evitar, mejor. Pensemos que la cantidad de recursos que consume un PC para calcular colisiones derivadas de mallas complejas es muy superior a la precisa para hacer lo propio con primitives colliders.

En resumen, que deberíamos usar los colliders de malla en objetos que sepamos positivamente que en nuestro juego se moverán poco o nada, que no estarán sometidos a colisiones continuas con otros objetos y que tengan una forma difícil de casar con un collider primitivo.


Por su parte, el primitive collider implica asignar a una malla un collider prefabricado por Unity, pudiendo meramente escoger entre las siguientes formas primitivas: esfera, caja, cápsula o rueda. Se trataría meramente de –teniendo nuestra malla seleccionada- irnos al menú Components=>Physics y seleccionar uno de los indicados colliders, para después moverlo de tal forma que encaje lo mejor posible con nuestra malla.

En ocasiones precisaremos usar varios colliders primitivos para cubrir toda la fisonomía de una malla. Esto se puede conseguir creando un gameobject vacío y emparentar dichos colliders como hijos de esta, para crear así una unidad manipulable, por decirlo de alguna forma.

Aunque este segundo sistema –primitive collider- es más trabajoso y antiestético que el anterior- mesh collider- es recomendable que en la medida de lo posible lo usemos para nuestras mallas.

En próximos capítulos ahondaremos en esto. De momento, lo dejamos por hoy.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 2 Comments
Con la tecnología de Blogger.