Ignora le collisioni con alcuni oggetti in determinati contesti


14

Sto realizzando un gioco di corse con macchine in Unity. L'auto ha un boost / nitro powerup. Durante il potenziamento, non vorrei essere deviato quando si scontrano con gli zombi, ma voglio essere deviato quando si scontrano con i muri.

D'altra parte, non voglio ignorare la collisione con gli zombi, perché voglio ancora colpirli all'impatto.

Come dovrei gestirlo? Fondamentalmente, quello che voglio è che l'auto non ruoti quando si scontra con determinati oggetti.

Risposte:


7

Valuta di manipolare i tuoi livelli in fase di esecuzione.

Abilitare / disabilitare le collisioni per determinati oggetti con interi livelli

Physics.IgnoreCollision e Physics.IgnoreLayerCollision consentono di disabilitare le collisioni tra due collider e tra due livelli, rispettivamente.

Se si desidera escludere un collider specifico dalle collisioni, non esiste un modo integrato per farlo. Se si utilizzano corpi rigidi non cinematici con collettori non trigger, ci sarà sempre una risposta anche se si tenta di filtrare le risposte per tag.

Il modo in cui l'abbiamo realizzato nel nostro progetto è stato quello di creare un livello chiamato "Vuoto". Il vuoto non si scontra con nulla.

Ora puoi disabilitare temporaneamente la collisione di un collider impostando il suo livello su "Vuoto" e riattivandolo ripristinando il suo vecchio livello.

Ecco l'essenza:

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;
}

Lo abbiamo fatto specificamente perché abilitare e disabilitare i collider che erano figli di corpi rigidi può davvero rovinare le cose in alcune circostanze. Quindi non è possibile disabilitare in modo affidabile parte di un collisore composto rigido, ma è possibile scambiare in modo affidabile attorno allo strato di una delle parti del collettore composto.

Ora la tua situazione specifica

Per ridurre l'impatto che la collisione di zombi ha sulla tua auto, prendi in considerazione la possibilità di innescare la cinematica dei tuoi zombi o di rendere la loro massa molto piccola (come float.Epsilon), quindi l'impatto non ha alcun effetto sul momento della macchina. All'impatto, puoi anche fare questo interruttore di livello, in modo che le successive collisioni non vengano innescate, anche se la prima applica una forza trascurabile alla carrozzeria.

Potresti anche passare a un livello che non si scontra con la macchina.

Potresti anche mettere un altro collider su zombi che si attivano in caso di razzie. In questo modo è possibile falsificare le forze di impatto OnTriggerEnter. Non puoi essere così preciso con esso, ma puoi approssimare dove le normali di contatto potrebbero essere state abbastanza bene da far divertire lo zombi da qualche parte.

Devi chiederti:

  • Voglio essere in grado di abbattere gli zombi travolti con la mia macchina o dovrebbero semplicemente riprodurre un'animazione di morte?

  • Mi interessa se la velocità dell'auto e la velocità angolare sono influenzate in modo minore colpendo gli zombi?


1

Chiama Physics.IgnoreCollision su tutti gli zombi, passando anche la funzione dell'oggetto giocatore, quando l'auto inizia a potenziare. Ciò farà sì che Unity non reagisca a eventuali collisioni tra il giocatore e gli zombi. Quando l'auto ha finito di potenziare, chiama di Physics.IgnoreCollisionnuovo ogni zombi, passandogli l'oggetto giocatore e falseper far ricominciare la risposta alla collisione.


Ma ciò significherebbe che non si scontreranno con nient'altro.
Paul Manta,

Farò qualche altra ricerca. L'unica cosa che mi viene in mente è: forse puoi ignorare la collisione restituendo false da OnCollisionEnter?
Wackidev,

@Wackidev Questo non è il caso.
Rhys van der Waerden,

@Paul ho modificato la mia risposta.
Wackidev,

0

Immagino che tu possa controllare i nomi degli oggetti, o aggiungere un valore ai nomi delle classi degli oggetti e poi controllarlo?

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");                
        }
    }
}

Quindi basta avere un'altra variabile che è possibile utilizzare per verificare il potenziamento e aggiungerla ai controlli.

EDIT: aggiunta questa variabile in.


Sa come essere informato delle collisioni; semplicemente non vuole che venga intrapresa alcuna azione di conseguenza. Vuole disabilitare la risposta di collisione integrata in alcuni casi.
Wackidev,

Sicuramente, qualsiasi cosa accada quando viene innescata la collisione tra le parentesi? Non ho mai usato l'unità prima, quindi non lo so, ma in cocos2d, e XNA ha fatto così.
Lewis

In realtà, Unity gestisce le collisioni tramite PhysX. OnCollisionEnter è solo un metodo di notifica; non è progettato per gestire la risposta effettiva alla collisione.
Wackidev,

0

Suppongo che stai usando il motore fisico per fare la "deviazione" automaticamente in base alla forma / massa quando le cose si scontrano insieme? in tal caso, cambia la massa dei tuoi zombi a un valore molto minimo e non influenzeranno la macchina.


0

Esistono due classi di risposte qui:

  1. Ignorare o disabilitare le collisioni
    • Queste soluzioni non risolveranno il problema, vuole che gli zombi volino quando vengono colpiti.
  2. Massa cambiante:
    • Questo è un buon approccio. Non dimenticare di modificare anche l'inerzia di conseguenza.
      • In alternativa, puoi cambiare la massa e l'inerzia delle auto quando aumenti (lo facciamo per ridurre l'impatto di tutti gli oggetti non cinematici su un'auto quando aumentano)
      • Ciò non dovrebbe influire sulla strada o sui muri assumendo che siano cinematici.

Spero che sia di aiuto!


Due delle risposte esistenti di sei anni fa già raccomandano l'approccio basato sulla massa che stai suggerendo qui. C'è qualche nuova strategia che vuoi aggiungere?
DMGregory

Chiedo scusa, non sono ancora riuscito a votare e volevo assicurarmi che Paul Manta non fosse fuori strada.
dwuLive
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.