Jump to content
Sign in to follow this  
nomoregames

ANSWERED Colliders dentro de el padre

Recommended Posts

Buenos d√≠as a todos¬†ūüėÉ

Tengo un objeto padre y dentro de este ay otros dos objetos hijo con un trigger cada uno, me gustaría saber cuando uno o el otro (de estos hijos) esta colisionando, mediante un script dentro de el padre.

Alguna idea?

Share this post


Link to post
Share on other sites

Crea un delegado y evento en cada hijo cuando el onTriggerEnter. Engancha los dos delegados en el objeto padre y sabr√°s cual ha sido invocado.

Share this post


Link to post
Share on other sites

Eso es lo que estoy haciendo ahora mismo (si por delegado te refieres a script, realmente no entiendo mucho la jerga), pero lo tengo como soluci√≥n temporal, ya que es mas engorroso a la hora de cambiar los objetos... no es muy "elegante"ūüĎ®‚Äćūüé®

Share this post


Link to post
Share on other sites

Mmmmm, me estoy miranda el vídeo una y otra vez, pero no lo acabo de entender

Serias tan amable de poner un ejemplo practico apto para muy in√ļtiles¬†ūüėÖ

Se consigo algo mas de claridad aviso 

Share this post


Link to post
Share on other sites

Lo he hecho a ojo. Es posible que hayan errores sint√°cticos:

// Asigna este gameobject al parent y las referencias de los children
public class cParent : MonBehaviour {
    [SerializeField] private cChild childOne;
    [SerializeField] private cChild childTwo;

    private void Start() {
        // Asignamos las funciones de los eventos
        this.childOne.onTriggerEvent += this.onTriggerEvent;
        this.childTwo.onTriggerEvent += this.onTriggerEvent;
    }

    private void OnDestroy() {
        this.childOne.onTriggerEvent -= this.onTriggerEvent;
        this.childTwo.onTriggerEvent -= this.onTriggerEvent;
    }

    public void onTriggerEvent(cChild child, string identifier) {
        switch(identifier) {
            case "childOne":
            // Corresponde con el cChild con identifier = "childOne"
            break;

            case "childTwo":
            // Corresponde con el cChild con identifier = "childTwo"
            break;
        }
    }
}

// Asigna el gameobject a cada child y ponle un nombre en el identifier
public class cChild : MonBehaviour {
    [SerializeField] private string identifier;

    public delegate void OnTriggerEvent(cChild child, string identifier);
    public event OnTriggerEvent onTriggerEvent;
    
    private void OnTriggerEnter(Collider other) {
        // Cuando entre en contacto y lance el trigger, se lanzar√° el evento
        this.onTriggerEvent?.Invoke(this, this.identifier);
    }
}

 

Share this post


Link to post
Share on other sites

ok... ok

Paso a paso para no caerme.

Cosas que (creo) he entendido

1 hour ago, iRobb said:

private void Start() { // Asignamos las funciones de los eventos this.childOne.onTriggerEvent += this.onTriggerEvent; this.childTwo.onTriggerEvent += this.onTriggerEvent; }

esta parte es como a√Īadir los eventos trigger de los otros objetos a el...

 

1 hour ago, iRobb said:

public void onTriggerEvent(cChild child, string identifier

(Editado: tampoco acabo de entender los parametros que a√Īades a onTriggerEvent, excepto el ultimo, string identifier¬†)

 

 

dentro de este, dependiendo de que numero ayas puesto como identificador, sabremos si el que ha colisionado es el 1 o el 2 (ahora hablare desde mi ignorancia absoluta.. no hubiera sido también posible en vez de usar string usar una lista ?? )

 

Hasta aquí mas o menos entiendo como funciona... pero no seria capaz de reproducirlo de nuevo (me falla un poco la sintaxis pero sobre todo, no acabo de entender la lógica... no me entra en la mollera) 

Segundo script

Primero le indicas a que game object pertenece este script, si al 1 o al 2

pero es lo √ļnico que entiendo de este script

Que es un public delegate void??? Eso se come?

Y bueno...

2 hours ago, iRobb said:

this.onTriggerEvent?.Invoke(this, this.identifier);

tiene un signo de pregunta, para que sirve?? y el invoke.... que hace exactamente, le manda a el script padre el identificador? Si es así, como lo hace???

 

 

 

Como puedes ver, por mi ignorancia, lo que necesito para entender esto, mas que un profesor, es un milagro...

As√≠ que si lo logras, ya puedes ir directo a casa de Elon musk a ense√Īarle tu haza√Īa. Lo tendr√°s a tus pies pidi√©ndote que te unas a su equipo de programadores XD

Share this post


Link to post
Share on other sites
2 minutes ago, nomoregames said:

ok... ok

Paso a paso para no caerme.

Cosas que (creo) he entendido

esta parte es como a√Īadir los eventos trigger de los otros objetos a el...

No. Son eventos. El evento puede ser cualquier cosa. En este caso porqué se lanza desde el OnTriggerEnter.

(Editado: tampoco acabo de entender los parametros que a√Īades a onTriggerEvent, excepto el ultimo, string identifier¬†)

Est√° bien a√Īadir desde el objeto que viene el evento por si necesitas obtener m√°s info public

 

 

dentro de este, dependiendo de que numero ayas puesto como identificador, sabremos si el que ha colisionado es el 1 o el 2 (ahora hablare desde mi ignorancia absoluta.. no hubiera sido también posible en vez de usar string usar una lista ?? )

Puedes utilizar lo que quieras. Lo de la List no entiendo porqué.

 

Hasta aquí mas o menos entiendo como funciona... pero no seria capaz de reproducirlo de nuevo (me falla un poco la sintaxis pero sobre todo, no acabo de entender la lógica... no me entra en la mollera) 

Segundo script

Primero le indicas a que game object pertenece este script, si al 1 o al 2

pero es lo √ļnico que entiendo de este script

Que es un public delegate void??? Eso se come?

Y bueno...

tiene un signo de pregunta, para que sirve?? y el invoke.... que hace exactamente, le manda a el script padre el identificador? Si es así, como lo hace???

Aquí ya te he roto la cabeza verdad? Para reducirlo, significa qué, si no hay un valor null en el event asignado, ejecuta (el Invoke). Es la sustitución de un (if blabla != null) { ejecuta }. Más elegante no?

 

 

 

Como puedes ver, por mi ignorancia, lo que necesito para entender esto, mas que un profesor, es un milagro...

As√≠ que si lo logras, ya puedes ir directo a casa de Elon musk a ense√Īarle tu haza√Īa. Lo tendr√°s a tus pies pidi√©ndote que te unas a su equipo de programadores XD

O qu√© el llegue a Marte ūüėĄ

T√ļ pru√©balo y luego debuga. Lo ver√°s mucho m√°s f√°cil.

 

Share this post


Link to post
Share on other sites

Para que no te lies, utiliza sendmessage.

al objeto hijo le pones el siguiente script

void OnCollisionEnter(Collision collision)
{
	transform.parent.gameObject.SendMessage("ColisionHijo", "Identificador");
}

 

 

y al padre este de aqui:
 

public void colisionHijo(string identificador)
{
       y aqui lo que quieras hacer con cada uno de los hijos
}

 

Share this post


Link to post
Share on other sites

@nomoregames la solución que intenta darte a entender @iRobb es bastante sencilla. 

¬ŅQu√© son los Eventos?
Los eventos son una forma de notificar a varios objetos un cambio.

¬ŅQu√© compone un evento?
Un evento est√° compuesto por 1 delegado.

¬ŅQu√© es un delegado?
Un delegado es la estructura de un método.

¬ŅQu√© es un m√©todo?
La implementación del cuerpo de un delegado.

Una definición super simple y no precisamente correcta.

--------------------

¬ŅCu√°ndo implementar eventos?
Los eventos son √ļtiles cuando necesitamos notificar m√ļltiples objetos de un cambio. Por ejemplo, podr√≠amos crear un evento "GameUpdateEvent" y llamarlo cada vez que se realiza un "GameLoop".

En tu caso, el problema es que necesitas generar un evento de colisión desde los objetos que estarían en la mano, entonces necesitas crear un Componente que contenga el evento y la lógica para ser disparado.

public class EventCollider : MonoBehaviour 
{  
    public delegate void TriggerDelegate(Collider collider);
    public event TriggerDelegate TriggerEvent;
    
    private void OnTriggerEnter(Collider collider) 
    {
        TriggerEvent?.Invoke(collider);
    }
}

La clase Event Collider implementa 1 Delegado, 1 Evento para el Delegado y la lógica para disparar el evento.

¬ŅC√≥mo creo un registro en el evento TriggerEvent?
Desde el controlador de tu jugador (donde deseas tener información de esta colisión) usando la función Start o Awake para asegurarnos de un unico registro en el evento, realizamos lo siguiente.

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private EventCollider m_leftCollider = null;
    [SerializeField]
    private EventCollider m_rightCollider = null;
    
    private void Start()
    {
        m_leftCollider.TriggerEvent += OnLeftCollider;
        m_rightCollider.TriggerEvent += OnRightCollider;
    }
    
    private void OnLeftCollider(Collider collider)
    {
        
    }
    
    private void OnRightCollider(Collider collider)
    {
        
    }
}

Hay que tener cuidado con los registros de eventos. Cuando no se vayan a utilizar mas por que el Componente PlayerController se destruye es importante eliminar el Registro.

private void OnDestroy()
{
    m_leftCollider.TriggerEvent -= OnLeftCollider;
    m_rightCollider.TriggerEvent -= OnRightCollider;
}

-----------

@leocub58 La solución que presentas es más simple de implementar, pero tiene un costo más elevado debido a la reflexión que se utiliza para este método. 

Share this post


Link to post
Share on other sites

Hola. Con uno de mis alumnos descubrimos que si en tu Parent tienes un collider y su hijo tiene un trigger, desde el propio parent también puede detectar vía código el OnTriggerEnter, aunque esté en su hijo. De alguna forma lo traspasa...

 

Lo llegamos a probar con sus variantes 2D, pero creo que también funciona en 3D...

Share this post


Link to post
Share on other sites
1 hour ago, pioj said:

Hola. Con uno de mis alumnos descubrimos que si en tu Parent tienes un collider y su hijo tiene un trigger, desde el propio parent también puede detectar vía código el OnTriggerEnter, aunque esté en su hijo. De alguna forma lo traspasa...

 

Sólo si los hijos no tienen Rigidbody kinemáticos. Cuando no los tienen, el collider del padre es la suma de los colliders de los hijos (fácil de olvidar, Compound Colliders), 

Si quieres que detecten las colisiones individualmente, tienen que tener sus propios Rigidbody (kinemático, puesto que si no deberías usar Joints supongo).

Si necesitas distinguir los OnTrigger (lo recibirán ambos) tendrás que chequear en el código (por ejemplo usando tags, el componente que tienen, o el nombre, o lo que sea).

Fuente: https://stackoverflow.com/questions/37991042/do-child-trigger-runs-parent-trigger-also

 

Edited by J Montes

Share this post


Link to post
Share on other sites

Bueno bueno

Con toda la información que me habéis aportado tengo mucho que procesar

Muchísimas gracias a iRobb, leocub58, francoe1, pioj y a @J Montes (no se como hacer que los nombres aparezcan encuadrados)

 


 

Share this post


Link to post
Share on other sites

Ok...

He estado probando cosillas

primero, siguiendo el consejo de iRob

On 4/24/2020 at 10:15 PM, iRobb said:

T√ļ pru√©balo y luego debuga. Lo ver√°s mucho m√°s f√°cil.

He aplicado sus scripts... y no se si he cometido alg√ļn error, pero me aparecen estos¬†errores

 

Captura.PNG

De modo que me he puesto a probar SendMessage y ay algo que creo he entendido...

Mediante sendMessage solo puedo mandar un parámetro.... si quiero poner 

gameObject.SendMessage("ejemplo",string 1,string 3)

pues no puedo. Supongo que para eso son √ļtiles los delegados...

 

Hehehe, ustedes juzgaran se he logrado sacarle algo de brillo al asunto...

Me siento como un hobbit ante argonath

Mejor uso otro símil, como alguien que esta a punto de ser examinado por el "todopoderoso" profesor

 

PD:  iRobb

Puedes utilizar lo que quieras. Lo de la List no entiendo porqué.

Se me a ido la olla, he confundido conceptos, pensaba que String era igual a¬†Array ūüėā

 

Buenas noches

Share this post


Link to post
Share on other sites
18 minutes ago, nomoregames said:

Se me a ido la olla, he confundido conceptos, pensaba que String era igual a¬†Array ūüėā

Realmente no est√°s tan alejado. En C# una String es un array de caracteresūüėā

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...