Tipos de colisión
La colisión en Unreal Engine es similar a la de Unity, pero con algunas diferencias que veremos aquí. Si has usado la detección de colisiones basada en capas de Unity, los ajustes de colisión del proyecto deberían verse similar a la matriz de colisión. Puedes acceder dirigiéndote a Editar > Ajustes del proyecto > Colisión. Si expandes la pestaña Preajuste, podrás ver todos los perfiles de preajuste predeterminado con una descripción de lo que hace cada uno.
Notarás que Unreal tiene algunas opciones más a la hora de resolver colisiones. Esto se trata más en profundidad en la Introducción sobre las colisiones en Unreal Engine. Este nivel de granularidad en la detección de colisiones es útil y puede ayudar al rendimiento del juego. Es importante entender que:
Los canales o los colisionadores individuales pueden establecerse en Bloquear, Solapar o Ignorar.
Un error típico es no establecer correctamente la opción Generar eventos de solapamiento en tus colisionadores cuando necesitas esos eventos.
La geometría estática debería bloquear y solapar, pero no necesariamente generar eventos de solapamiento o impacto, ya que no es necesario para la jugabilidad.
Se pueden generar eventos de solapamiento incluso si un objeto bloquea a otro, en especial cuando se desplazan a grandes velocidades. En Unity, esto puede ser un problema si modificas directamente la traslación en lugar de un componente de cuerpo rígido. Esto pasa por alto las consideraciones de la física.
En Unreal, cuando invocas una función que actualiza la transformación de un actor, hay dos parámetros booleanos que dictan cómo mover al actor:
Barrido activa los solapamientos y detiene al actor antes de llegar a destino si está bloqueado. Teletransporte determina si la velocidad de la física se conserva o no.
Los canales pueden también ser usados para los Trazados, que son equivalentes al casteo de física de Unity (es decir, Raycast, SphereCast etc.). Puedes pasar el canal durante tu llamada de función Trazado de línea de la misma forma en que pasarías la máscara de la capa en un Raycast en Unity.
Tipos de colisiones personalizadas en Parrot
Parrot tiene configurados algunos canales de objetos de colisión personalizados: Player, Cannonball y Enemy.
Al añadir estos tipos de objeto, Parrot puede controlar cómo estos canales de objetos interactúan con los canales de trazado cuando se producen trazados de colisión en el entorno. Se establece una respuesta predeterminada para lo que sucedería generalmente, pero puede personalizarse si así se desea. Parrot también tiene unos preajustes de canal de trazado personalizados: Player, OverlapAllPlayers, BlockAllPlayers, Cannonball y Enemy.
Estos preajustes son especialmente útiles para activadores del juego. Por ejemplo, OverlapAllPlayers puede ignorar todas las colisiones y responder solamente a eventos de colisión con tipos de objeto de colisión de jugador. Si observas los ajustes de colisión para diferentes mallas en el juego, verás que estos preajustes se usan con frecuencia.
Los ajustes de colisión pueden también ser personalizados por cada malla.
Límites del entorno
Al crear niveles, hay que tener en cuenta los Límites del entorno. Esto se puede configurar en Ajustes del entorno > Entorno. Puedes implementar un tipo de daño personalizado para cuando un actor interactúa con estos límites de entorno definidos. Los límites de Parrot usan una combinación de ajustes de entorno KillZ y volumen de activación Fuera de los límites.
Volúmenes de activación
Unreal Engine tiene actores de volumen de activación integrados (consulta Actores de volumen de activación en Unreal Engine) que pueden usarse para activar eventos. Algunos ejemplos de donde los desarrolladores lo usan en Parrot son los volúmenes de activación Fuera de los límites y Línea de llegada. Los volúmenes de activación a menudo se usan junto con el blueprint de nivel (consulta la documentación para desarrolladores sobre Blueprints de nivel en Parrot), aunque no es algo obligatorio. El activador de Parrot para Fuera de los límites es un activador de caja con un gráfico de eventos sencillo:
Si miras los ajustes de colisión del actor en el panel de detalles, verás que el preajuste de canal de colisiones hace casi todo el trabajo.
Recolección de potenciadores
Veamos un ejemplo práctico del sistema de colisiones con la implementación de recolección de potenciadores de Parrot. Si abres BP_PickupBase en Content > Blueprints > Pickups y observas el visor, podrás ver la jerarquía que contiene el componente de colisión.
Los ajustes de colisión y el Fuera de los límites tienen un preajuste de activación que genera eventos de solapamiento con los jugadores:
Si observas el gráfico de eventos, verás el evento ActorBeginOverlap con Otro actor como parámetro. Este evento funciona de manera similar a OnCollisionEnter en Unity. La diferencia es que en lugar de pasar un componente colisionador, se te proporciona el propio actor.
Parrot proyecta para comprobar que el actor es un jugador que se ha solapado. Ahí se llama al evento OnPickedUp. Esto le permite a las clases de blueprint derivadas definir su propio comportamiento para OnPickedUp mientras que la clase base se encarga del evento de solapamiento de actores.
Los desarrolladores usan el blueprint base para gestionar que todos los objetos recolectados reproduzcan un sonido y generen efectos de partículas. Las variables de sonido de recolección y de efecto de partículas se pueden editar por instancia, así que pueden ser establecidas en los valores por defecto de clase de las clases derivadas. Los valores por defecto de clase se encuentran en el editor de blueprints en la parte superior, junto al botón de compilación:
Puedes ver un ejemplo de valores por defecto de clase cambiados en la recolección de velocidad, que usa el sistema Niagara con partículas verdes (a diferencia de la recolección de corazones, que usa partículas rosas). Del mismo modo, la malla de recolección puede configurarse en blueprints derivados. El último paso en la lógica de solapamiento es destruir al actor de recolección, ya que no queremos que persista una vez recogido por el jugador.
Con solo unos cuantos nodos ya puedes crear una buena lógica que puede fácilmente expandirse a blueprints derivados. Todos los blueprints derivados parten de un evento de solapamiento vinculado al actor.
Personaje jugable saltando sobre un enemigo
Otro gran ejemplo que podemos ver es cuando el jugador salta sobre un enemigo. La cápsula de colisión del enemigo es del tipo ‘enemy’, y colisionará con los tipos de objetos del jugador. Los enemigos con espadas también tienen un evento de solapamiento similar. Se les conoce comúnmente como "cajas de impacto", y son el área donde un ataque es efectivo.
Pero cuando un jugador salta sobre un enemigo, ¿cómo lo soluciona Parrot? La solución fue colocar una caja de daño en las cabezas de los enemigos. Cuando el jugador solapa este volumen de la caja de daño, el personaje jugable puede hacer una serie de chequeos para ver si se trata de un salto válido basado en la ubicación del personaje, la ubicación de la caja de daño y la extensión de la caja. Si pasan los chequeos, el jugador puede realizar el salto e impactar al enemigo. El trabajo pesado una vez más lo hacen los canales de colisión, que filtran solo los solapamientos que le interesan a Parrot: un objeto de colisión de jugador y un enemigo en el volumen de la caja de daño.