Ignorar colisiones con algunos objetos en ciertos contextos.

14

Estoy haciendo un juego de carreras con autos en Unity. El auto tiene un impulso de encendido / nitro. Mientras aumenta, no me gustaría que me desviaran al chocar con zombies, pero sí quiero que me desvíen al chocar con las paredes.

Por otro lado, no quiero ignorar la colisión con zombis, porque todavía quiero golpearlos en el impacto.

¿Cómo debería manejar esto? Básicamente, lo que quiero es que el automóvil no gire al chocar con ciertos objetos.

Paul Manta
fuente

Respuestas:

7

Considera manipular tus capas en tiempo de ejecución.

Habilitar / deshabilitar colisiones para ciertos objetos con capas enteras

Physics.IgnoreCollision y Physics.IgnoreLayerCollision le permiten desactivar las colisiones entre dos colisionadores y entre dos capas, respectivamente.

Si desea excluir un colisionador específico de las colisiones, no hay una forma integrada de hacerlo. Si está utilizando cuerpos rígidos no cinemáticos con colisionadores sin disparador, siempre habrá una respuesta, incluso si intenta filtrar las respuestas por etiqueta.

La forma en que logramos esto en nuestro proyecto fue crear una capa llamada "Void". El vacío no choca con nada en absoluto.

Ahora puede deshabilitar temporalmente la colisión de un colisionador configurando su capa en "Void" y volviendo a habilitarla restaurando su capa anterior.

Aquí está la esencia:

int oldLayer = -1;
int voidLayer;

void Start()
{
    voidLayer = LayerMask.NameToLayer("Void");
}

void DisableCollider(Collider col)
{
    oldLayer = col.gameObject.layer;
    col.gameObject.layer = voidLayer;
}

void EnableCollider(Collider col)
{
    col.gameObject.layer = oldLayer;
}

Hicimos esto específicamente porque habilitar y deshabilitar colisionadores que eran hijos de cuerpos rígidos realmente puede arruinar las cosas en algunas circunstancias. Por lo tanto, no puede deshabilitar de manera confiable parte de un colisionador compuesto de cuerpo rígido, pero puede intercambiar confiablemente alrededor de la capa de una de las partes del colisionador compuesto.

Ahora tu situación específica

Para reducir el impacto que tiene la colisión de zombis en tu auto, considera hacer que tus zombies sean los disparadores cinemáticos de cuerpo rígido, o de lo contrario hacer que su masa sea muy pequeña (como flotador, Epilon), por lo que el impacto tiene un efecto cero en el impulso del auto. En el impacto, también puede hacer este cambio de capa, para que no se activen colisiones posteriores, incluso si la primera aplica una fuerza insignificante a la carrocería del automóvil.

Incluso podría cambiarlos a una capa que simplemente no choque con el automóvil.

También podría poner otro colisionador sobre zombies que se activan en el atropello. De esta manera, puedes falsificar las fuerzas de impacto en OnTriggerEnter. No puede ser tan preciso con eso, pero puede aproximarse a dónde las normales de contacto pueden haber sido lo suficientemente buenas como para lanzar al zombi a un lugar divertido.

Tienes que preguntarte a ti mismo:

  • ¿Quiero poder golpear a los zombis atropellados con mi coche, o deberían simplemente reproducir una animación de muerte?

  • ¿Me importa si la velocidad del automóvil y la velocidad angular se ven afectadas de manera más pequeña al golpear a los zombis?

michael.bartnett
fuente
1

Llama a Physics.IgnoreCollision en todos los zombies, pasando también la función del objeto del jugador, cuando el auto comienza a aumentar. Esto hará que Unity no reaccione a ninguna colisión entre el jugador y los zombies. Cuando el auto termine de aumentar, llama Physics.IgnoreCollisionnuevamente a cada zombi, pasa el objeto del jugador y falseprovoca que la respuesta de colisión comience nuevamente.

Wackidev
fuente
Pero eso significaría que tampoco chocarán con nada más.
Paul Manta
Investigaré un poco más. Lo único en lo que puedo pensar es: ¿quizás pueda ignorar la colisión devolviendo falso de OnCollisionEnter?
Wackidev
@Wackidev Este no es el caso.
Rhys van der Waerden
@Paul He editado mi respuesta.
Wackidev
0

Supongo que puede verificar los nombres de los objetos o agregar un valor de nombre a las clases de objetos y luego verificar eso.

bool boosting = false; //need a trigger in the game to set this to true.

function OnCollisionEnter(theCollision : Collision)
{   
    if (boosting == true)
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit during boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit during boost");            
        }
    }
    else 
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit not in boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit not in boost");                
        }
    }
}

Luego, solo tiene otra variable que puede usar para verificar el aumento y agregarla a los controles.

EDITAR: se agregó esta variable en.

Luis
fuente
Él sabe cómo ser notificado de colisiones; simplemente no quiere que se tomen medidas como resultado. Quiere deshabilitar la respuesta de colisión incorporada en ciertos casos.
Wackidev
¿Seguramente pase lo que pase cuando se dispare la colisión entre los corchetes? No he usado la unidad antes, así que no lo sé, pero en cocos2d, y XNA se hace así.
Lewis
En realidad, Unity maneja las colisiones a través de PhysX. OnCollisionEnter es solo un método de notificación; No está diseñado para manejar la respuesta de colisión real.
Wackidev
0

Supongo que está utilizando el motor de física para hacer la 'desviación' automáticamente en función de la forma / masa cuando las cosas chocan entre sí. Si ese es el caso, cambie la masa de sus zombies a un valor mínimo y no afectarán el automóvil.

ADB
fuente
0

Aquí hay dos clases de respuestas:

  1. Ignorar o deshabilitar colisiones
    • Estas soluciones no resolverán el problema, él quiere que los zombis salgan volando cuando los golpeen.
  2. Masa cambiante:
    • Este es un buen enfoque. No olvides cambiar también la inercia en consecuencia.
      • Alternativamente, puede cambiar la masa e inercia de los automóviles cuando aumenta (hacemos esto para reducir el impacto de todos los objetos no cinemáticos en un automóvil cuando aumenta)
      • Esto no debería afectar el camino o los muros suponiendo que sean cinemáticos.

¡Espero que esto ayude!

dwuLive
fuente
Dos de las respuestas existentes de hace seis años ya recomiendan el enfoque basado en la masa que está sugiriendo aquí. ¿Hay alguna estrategia nueva que quieras agregar?
DMGregory
Pido disculpas, todavía no puedo votar y quería asegurarme de que Paul Manta no fuera desviado.
dwuLive