Problema básico: el motor de física de Unity produce colisiones extrañas cuando un jugador se mueve sobre una superficie plana hecha de más de un Colisionador. Las colisiones fantasmas ocurren en las uniones entre colisionadores y se expresan como dos comportamientos:
Esto parece ser un problema con los motores de física en general, según esta charla de Bennett Foddy:
https://www.youtube.com/watch?v=NwPIoVW65pE&ab_channel=GDC
Especificaciones del juego: en mi caso, el jugador se mueve a través de un agujero de gusano generado por procedimientos, compuesto por objetos Segment utilizando un MeshCollider. El agujero de gusano gira aleatoriamente a través del espacio 3D, mientras que el ancho y la altura cambian dinámicamente. El jugador puede moverse 360 grados alrededor del interior del túnel (la dirección de la gravedad es relativa a la posición).
Esto hace que las soluciones más simples que he encontrado no sean prácticas. Esos incluyen:
Logré marcar estas colisiones erróneas en OnCollisionEnter(). Este método en PlayerController funciona bien para identificar estas colisiones erróneas y levantar una bandera.
private void OnCollisionEnter(Collision other) { if (other.gameObject.tag != "Tunnel"){return;} // Bit mask for tunnel layer. int tunnelLayerMask = 1 << 10; // Get the direction from the nearest Segment's origin to the collision point. Vector3 toCollision = other.contacts[0].point - nearestSegment.transform.position; if (Physics.Raycast(nearestSegment.transform.position, toCollision, out RaycastHit hit, 100f, tunnelLayerMask)) { // Flag the collision if the detected surface normal // isn't equal to the collision normal. if (other.contacts[0].normal != hit.normal) { colFidelityFlag = true; } } }
Pero estoy completamente perdido cuando se trata de resolver el problema con gracia.
Actualmente, solo estoy almacenando en caché la velocidad del jugador en cada cuadro. Si se marca una colisión, sobrescribo la velocidad resultante con la velocidad almacenada en caché del cuadro anterior. Esto funciona para la mayoría de las condiciones: el jugador se esconde imperceptiblemente en el suelo para un marco y pasa la articulación infractora. Pero bajo velocidades lo suficientemente altas o interacciones con obstáculos dentro del túnel, es posible que el jugador sea expulsado a través del piso y al espacio. No quiero limitar demasiado la velocidad del jugador, ya que la sensación del juego se basa parcialmente en la alta velocidad y las colisiones fuertes.
¿Alguien sabe de una mejor manera de resolver estas colisiones erróneas?
Esto se llama "vértices fantasmas", y sucede si tiene como 2 colisionadores de caja (o algo equivalente) y están conectados entre sí. Puede intentar unir los colisionadores para que, en lugar de 2 colisionadores separados conectados, tenga uno solo.
Aquí los vértices fantasma se explican con más detalle: https://www.iforce2d.net/b2dtut/ghost-vertices