Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Como enviar dos variables en un SendMessage

Iniciado por TheCodeMaker, Agosto 06, 2017, 08:18:30 PM

Tema anterior - Siguiente tema
Necesito enviar dos variables con SendMessageUpwards para, antes de destruir el objecto, enviarle al padre la posición y rotación de este.

no entiendo muy bien lo que quieres decir, pero intenta concatenar las variables y usar split, aunque seguro que hay algo mejor, como mandar eso antes de destruirlo jajaja

Cita de: Kvashir date=1502054738no entiendo muy bien lo que quieres decir, pero intenta concatenar las variables y usar split, aunque seguro que hay algo mejor, como mandar eso antes de destruirlo jajaja
   


Es una buena solución, sí. Condensarlos en una string con un delimitador...

Cita de: pioj date=1502178924Es una buena solución, sí. Condensarlos en una string con un delimitador...


Pues para mi es una solucion un tanto ... sin palabras; como aquel que intenta reinventar la rueda. Si se trata de enviar la posicion y rotacion de un gameobject, lo mas sencillo es enviar el propio objeto "transform" que ya tiene almacenados ambos datos.

Serializar el componente Transform y Deserializar....
 
Capturar un Evento por parte del Padre.
 
Etc... 
 
Pero usar SendMessageUpwards() no es conveniente! ...
 
 
 
Tienes que dejar de pensar en componentes y más bien tratar de armar un ambiente estructurado y en sintonía, utilizar la mínima cantidad de MonoBehaviour y abstraer todo al máximo logrando así mantener tu aplicación limpia, optimizada y expansible.

Cita de: francoe1 date=1502212982Tienes que dejar de pensar en componentes y más bien tratar de armar un ambiente estructurado y en sintonía, utilizar la mínima cantidad de MonoBehaviour y abstraer todo al máximo logrando así mantener tu aplicación limpia, optimizada y expansible.
   


Amén, es la parte claramente que mas tiempo y planificacion lleva, el resto son triggers, vectors y quaternions, una papita.

Cita de: Arthure date=1502188060Pues para mi es una solucion un tanto ... sin palabras; como aquel que intenta reinventar la rueda. Si se trata de enviar la posicion y rotacion de un gameobject, lo mas sencillo es enviar el propio objeto "transform" que ya tiene almacenados ambos datos.
   


lo se, es una castaña eso, pero como tampoco se explicó mejor XD, tambien dije que seguro hay algo mejor que hacer eso, yo casi nunca uso MonoBehaviour, solo en casos que no hay otra manera de conseguir mi objetivo.
 
 

Cita de: francoe1 date=1502212982Tienes que dejar de pensar en componentes y más bien tratar de armar un ambiente estructurado y en sintonía, utilizar la mínima cantidad de MonoBehaviour y abstraer todo al máximo logrando así mantener tu aplicación limpia, optimizada y expansible.
   


Si algún día compartes un ejemplo de todo esto que fomentas, la Comunidad y to te lo agradeceremos efusivamente...

Agosto 09, 2017, 09:41:24 PM #8 Ultima modificación: Agosto 09, 2017, 09:47:08 PM por francoe1
Cita de: pioj date=1502303919Si algún día compartes un ejemplo de todo esto que fomentas, la Comunidad y to te lo agradeceremos efusivamente...
   


Claro, siempre que puedo estoy compartiendo, pero en mis momentos libres creó material que luego pueda obtener ganancias, pero estoy muy limitado con el tiempo.
 
En este caso, no se explica claramente lo que está necesitando, pero supongamos que el tiene un objeto que emparenta a otro.
 
(Player):GameObject // Jugador

        (Box Temp):GameObject // Caja temporal que se destruye al pasar por algún lugar.
 
Supongamos que el jugador necesita saber si la caja temporal se ha destruido, de ser así, obtener los valores del componente transform de la caja.
 
Por lo general, este tipo de problemas se plantean de la siguiente forma ¿La caja le avisa al Jugador que se destruyó?, ¿El jugador comprueba que la caja se existe? ... pero todas estas dudas no son más que malas ideas, partamos desde un inicio. ¿Por que el jugador necesita saber si la caja se destruyo?, ¿Y?¿Si otro componente tambien lo requiere? ... siempre estas son las preguntas futuras, las que hacen que el desarrollo de una aplicación se vuelva inestable. Entonces ¿Cómo realizarlo de la manera correcta?, bien, en primer lugar, vamos a tratar de centralizar los eventos, es decir, creamos una clase estática la cual puede llevar el nombre de GameEvents donde registramos todos los eventos del juego (con antelación deberíamos tener el diseño de nuestra aplicación, está más que claro que de lo contrario hay pocas posibilidades de éxito). Veamos un Ejemplo:
 

public static class GameEvents
{
public delegate DestroyObjectDelegate(GameObject go);
     public static event DestroyObjectDelegate DestroyObjectEvent = delegate {};
public static void DestoyObject(GameObject go)
    {
         DestroyObjectEvent.Invoke(go);
         //Unity ...
         MonoBehaviour.DestoyObject(go);
    }
}

 
De esta manera nosotros podríamos desde cualquier lugar de la aplicación capturar el evento requerido... Ejemplo.
 

public class Player : MonoBehaviour
{
private void Start()
    {
   GameEvents.DestroyObjectEvent += OnDestroyObject;
    }

private void OnDestroyObject(GameObject go)
    {
   if(go.name == "Box Temp") Debug.Log("¡Objetivo destruido!");
    }
}

 
Podríamos utilizar la misma implementación desde cualquier lugar del proyecto, debido a que estamos trabajando basado en eventos.
 
 
 
Todo esto es una mirada muy por arriba de como se hacen las cosas, en realidad tiene aun muchos pasas antes de llegar a esto, como son las cases de Argumentos, el diseño de delegados, componentes, clases, dependencias...
 
 
 
1º Aprender a utilizar eventos(event y delegate)
 
2º Aprender a utilizar enumeradores, entender como funcionan internamente (IEnumerator)
 
3º Aprender a utilizar clases Abstractas, Interfaces, Estructuras saber donde y cuando utilizarlas.
 
4º La decisión de utilizar un Componente MonoBehaviour es crítico, tratemos de no hacerlo.
 
En este punto me gusta mucho dar el ejemplo del movimiento de las actores dentro de un juego, por ejemplo, tenemos dos tipos de personajes con movimientos totalmente diferentes, muchos frente a este problema crearán un componente diferentes para cada uno, 2 prefabs, y se empieza a complicar todo, otros recurrirán a la abstracción, mi recomendación, utilizar clases no serializadas para los diferentes comportamientos, es decir.
 

public class Player : MonoBehaviour
{
private Motor _motorJumper = new MJumper();
private Motor _motorRunner = new MRunner();
private Motor _current;
private void SetMotor(int mode)
    {
   switch(mode)
   {
      case 0: _current = _motorJumper; break;
      case 1: _current = _motorRunner; break;
   }
    }
private void Update()
    {
   _current.Run(Input.Axis*****);
    }
}
public class Motor
{
public virtual void Run(Vector3 axis){}
}
public class MJumper : Motor
{
public override void Run(Vector3 axis)
    {
   movimientos..
    }
}
public class MRunner : Motor
{
public override void Run(Vector3 axis)
    {
   movimientos..
    }
}

 
Existen muchos ejemplos, en cuanto tenga tiempo voy a terminar una serie de tutoriales que tengo ya en edición, sobre un sistema de armas bastante completo, donde trato de explicar la importancia de cada técnica... 

Cita de: francoe1 date=1502307684Claro, siempre que puedo estoy compartiendo, pero en mis momentos libres creó material que luego pueda obtener ganancias, pero estoy muy limitado con el tiempo.
   
   
      En este caso, no se explica claramente lo que está necesitando, pero supongamos que el tiene un objeto que emparenta a otro.
   
   
      (Player):GameObject // Jugador

              (Box Temp):GameObject // Caja temporal que se destruye al pasar por algún lugar.
   
   
      Supongamos que el jugador necesita saber si la caja temporal se ha destruido, de ser así, obtener los valores del componente transform de la caja.
   
   
      Por lo general, este tipo de problemas se plantean de la siguiente forma ¿La caja le avisa al Jugador que se destruyó?, ¿El jugador comprueba que la caja se existe? ... pero todas estas dudas no son más que malas ideas, partamos desde un inicio. ¿Por que el jugador necesita saber si la caja se destruyo?, ¿Y?¿Si otro componente tambien lo requiere? ... siempre estas son las preguntas futuras, las que hacen que el desarrollo de una aplicación se vuelva inestable. Entonces ¿Cómo realizarlo de la manera correcta?, bien, en primer lugar, vamos a tratar de centralizar los eventos, es decir, creamos una clase estática la cual puede llevar el nombre de GameEvents donde registramos todos los eventos del juego (con antelación deberíamos tener el diseño de nuestra aplicación, está más que claro que de lo contrario hay pocas posibilidades de éxito). Veamos un Ejemplo:
   
   

public static class GameEvents
{
public delegate DestroyObjectDelegate(GameObject go);
     public static event DestroyObjectDelegate DestroyObjectEvent = delegate {};
public static void DestoyObject(GameObject go)
    {
         DestroyObjectEvent.Invoke(go);
         //Unity ...
         MonoBehaviour.DestoyObject(go);
    }
}

   
      De esta manera nosotros podríamos desde cualquier lugar de la aplicación capturar el evento requerido... Ejemplo.
   
   

public class Player : MonoBehaviour
{
private void Start()
    {
   GameEvents.DestroyObjectEvent += OnDestroyObject;
    }

private void OnDestroyObject(GameObject go)
    {
   if(go.name == "Box Temp") Debug.Log("¡Objetivo destruido!");
    }
}

   
      Podríamos utilizar la misma implementación desde cualquier lugar del proyecto, debido a que estamos trabajando basado en eventos.
   
   
      Todo esto es una mirada muy por arriba de como se hacen las cosas, en realidad tiene aun muchos pasas antes de llegar a esto, como son las cases de Argumentos, el diseño de delegados, componentes, clases, dependencias...
   
   
      1º Aprender a utilizar eventos(event y delegate)
   
   
      2º Aprender a utilizar enumeradores, entender como funcionan internamente (IEnumerator)
   
   
      3º Aprender a utilizar clases Abstractas, Interfaces, Estructuras saber donde y cuando utilizarlas.
   
   
      4º La decisión de utilizar un Componente MonoBehaviour es crítico, tratemos de no hacerlo.
   


No es mi intencion ofender ... pero a mi me parece una chorrada como utilizas los delegados y eventos eh ! Sobretodo teniendo en cuenta que segun algun comentario se da a entender algo parecido a "para esto hay que recorrer un gran camino, estudiar muchos años y cuando crezcais podreis ser como dios" xDDD
 
El problema de querer hacer ver que el uso de los delegados es algo muy avanzado, es que los que somos programadores (no me refiero a Unity) los utilizamos desde hace mucho tiempo, y los que no pretenden ser programadores se las va a sudar ... Como si se quiere decir que es la panacea.
 
Dicho eso, comentare porque encuentro una chorrada ese uso de los delegados ...
 
En primer lugar, una clase estatica para los eventos ??? Como se dice en mi tierra, "oh dios mio !" ... exceptuando mi sobrina que es muy chula ella y diria "ohh my god !" xDDD Para decir que hay que estudiar mucho y entender como y para que se utilizan las cosas, no vamos muy sobrados
 
Comenzando porque no se que pinta ese delegate ahi, pero eso es otra historia que no viene a cuento ... imagino que el codigo queda mas cool con la palabra delegate xDDD
 
Continuando porque un evento (no la captura y lo que se haga con ese evento) sino el evento se ejecute desde una clase estatica ... ademas de ser de chiste de por si, estas obligado a hacer la funcion publica, que ademas es un delegado, y eso para alguien que dice que hay que mantener una aplicacion limpia, optimizada y expansible suena a chiste malo.
 
En mi mundo un evento (accion) lo ejecuta un objeto, y otros objetos capturan estos eventos ... en tu caso coges y llevas tanto la accion como la captura de dicha accion a una clase estatica, dices que asi hay que hacerlo porque evitas utilizas MonoBehaviour y te quedas tan ancho
 
Solo dire que si una vez "capturado" el evento por el Player este debe comprobar el tag, name o cualquier otro atributo del objeto destruido para saber si debe hacer una accion o no ... es que se nota que es un codigo bien hecho, lo que cualquiera llamaria una aplicacion limpia, optimizada y expansible
Cita de: francoe1 date=1502307684En este punto me gusta mucho dar el ejemplo del movimiento de las actores dentro de un juego, por ejemplo, tenemos dos tipos de personajes con movimientos totalmente diferentes, muchos frente a este problema crearán un componente diferentes para cada uno, 2 prefabs, y se empieza a complicar todo, otros recurrirán a la abstracción, mi recomendación, utilizar clases no serializadas para los diferentes comportamientos, es decir.
   
   

public class Player : MonoBehaviour
{
private Motor _motorJumper = new MJumper();
private Motor _motorRunner = new MRunner();
private Motor _current;
private void SetMotor(int mode)
    {
   switch(mode)
   {
      case 0: _current = _motorJumper; break;
      case 1: _current = _motorRunner; break;
   }
    }
private void Update()
    {
   _current.Run(Input.Axis*****);
    }
}
public class Motor
{
public virtual void Run(Vector3 axis){}
}
public class MJumper : Motor
{
public override void Run(Vector3 axis)
    {
   movimientos..
    }
}
public class MRunner : Motor
{
public override void Run(Vector3 axis)
    {
   movimientos..
    }
}

   
      Existen muchos ejemplos, en cuanto tenga tiempo voy a terminar una serie de tutoriales que tengo ya en edición, sobre un sistema de armas bastante completo, donde trato de explicar la importancia de cada técnica... 
   


Esto ultimo que se decia te hubiera podido quedar mucho mejor ... pero tambien es un poquito una cagada; porque el uso de la clase Motor, junto a sus derivadas, es muy bueno para hacer un codigo mas limpio y expansible (lo de optimizado vamos a dejarlo en el aire) pero cuando se trata de hacer una maquina de estados.
 
Pero si solo es para mover un personaje, por muy distinto que se muevan ... una clase abstracta, con la funcion abstracta encargada de movimiento para que obligue a implementarla en cada uno de los personajes, y marchando.

Agosto 10, 2017, 04:38:25 PM #10 Ultima modificación: Agosto 10, 2017, 04:38:45 PM por francoe1
@Arthure Lo comente abajo, que es algo complicado de explicar, cuando alguien está comenzando se le hace muy dificil entender como funcionan los delegados, los eventos, los argumentos, para que y porque se utilizan. Por ejemplo, si vamos a lo teórico, un delegado se parece mucho a un puntero de C, este vendría a ser una referencia a un método cualquiera, es decir no está explícitamente declarado para el compilador. Pero, ¿Quién podría entender estas palabras?, muchos ni siquiera saben que es un compilador...
 
Cita de: francoe1 date=1502307684Todo esto es una mirada muy por arriba de como se hacen las cosas, en realidad tiene aun muchos pasas antes de llegar a esto, como son las cases de Argumentos, el diseño de delegados, componentes, clases, dependencias...
   


En esta parte especificó que en realidad esto es algo muy disparado...
 
De todos modos gracias por la corrección, pero antes la burla o "la mala manera de corregir" estaria bueno que muestres de que manera cada implementación sería mejor, y que al mismo tiempo, personas que no conocen mucho sobre el tema puedan llegar a entender.
 
Saludos. 

Cita de: Arthure date=1502364702Comenzando porque no se que pinta ese delegate ahi, pero eso es otra historia que no viene a cuento ... imagino que el codigo queda mas cool con la palabra delegate xDDD
   


No se mucho, (bueno muy poquito) de delegates, a mi tambien me confundio su uso un poco (en Unity oficial) ya que lo especifico de c# no es mi palo, pero cuando se da el evento vos llamas a un "event delegate" por decirlo asi simple, y cada listener ejecuta su metodo propio, que suscribió previamente a la escucha, entonces como haces esto sin delegates? tenes multiples metodos distintos, esa es la idea del delegate en primer instancia, que haga de puntero de metodos por asi decirlo, porque el delegate asi como lo ves lo usan en Unity y en cada porcion de codigo que he visto. Lo ideal seria entenderlo al 100% que no es mi caso pero estaria bueno Arthure que si respondes diciendo que todo es chiste digas porque exactamente, si en vez de tirar esto y lo otro es chiste digas ese delegate no va ahi o de esa forma por tal y tal razon, es "mejor" usar tal por tal y tal razon. Me entendes? sino siempre suena a bardo y mas viniendo del famoso Arthure .
 
Mi manejador de eventos era super sencillo, un monobehavior de toda la vida con sus eventos creados, chequeando si de dan las acciones correspondientes para disparar el evento, quien lo escuche que haga lo suyo. Pero despues lo eliminé ya que no hacia nada y me metia un monobehaviour sin sentido, asi que cada autor del evento tiene su evento static, mas especifico su "static event -delegate-" (habra tres en el juego maximo, nada raro) por ejemplo:
 

public delegate void PlayerDeadDelegate ();
public static event PlayerDeadDelegate PlayerDead;

 
 
 
Cita de: Arthure date=1502364702Pero si solo es para mover un personaje, por muy distinto que se muevan ... una clase abstracta, con la funcion abstracta encargada de movimiento para que obligue a implementarla en cada uno de los personajes, y marchando.
   


El usar o no abstract o virtual(overrride) no depende si es lo mismo prefiero esto o lo otro (a veces por comodidad mmm si),en un caso (abstract) obligas como bien decis a implementar el metodo (lo ideal es que cada clase vaya tomando su forma y asi obligar cada funcionalidad, algo asi como el uso de interfaces) y en el otro ya esta implementado por la clase base (la idea es que no sea siempre un {  }  ), algo asi como si no pones un Start() o Update() Unity ya sabe que hacer aunque no lo implementes, en su behaviour. A lo que iba es que el usarlo sirve para tener distintas comportamientos entre base y derivada, pero si en este caso Motor no pincha ni corta me parece que lo correcto seria un abstract como decis.

Creo de @Arthure no entendió o yo me mal exprese en el sentido de cómo estaba interpretando el mensaje, la idea era dar como una "MALA IDEA" de cómo centralizar un poco las aplicaciones.   
 
Cita de: lightbug date=1502376038public delegate void PlayerDeadDelegate (); public static event PlayerDeadDelegate PlayerDead;
   


Esto puede estar bien, o mal, dependiendo de cuántos jugadores estén dentro del juego, pero no por eso deja de ser una buena idea o solución.
 
Por lo general en el desarrollo de un juego se centralizan todos los eventos, esto hace que el "DEBUG" sea más sencillo, la recopilación de información sea más ordenada. ¿Como sabrás cuantas veces murio el jugador? o ¿Cuantos enemigos has matado? ... 

 
 
Cita de: Arthure date=1502364702En mi mundo un evento (accion) lo ejecuta un objeto, y otros objetos capturan estos eventos ... en tu caso coges y llevas tanto la accion como la captura de dicha accion a una clase estatica, dices que asi hay que hacerlo porque evitas utilizas MonoBehaviour y te quedas tan ancho


¿Cómo lo implementamos mis preguntas basándonos en tu teoría?, ¿Eventos estáticos? - ¿Referencias? ... Pienso, no es mejor una clase "estática" que se encarge de obtener todos estos eventos, es decir, si muere el jugador llama a una función dentro de mi clase GameEvents y esta llama a un evento... El evento es capturado por quien quiera, pero la llamada tambien, eso se llama "Centralización" - ¡No creo que este mal este punto! Quizás el ejemplo no es el correcto, pero este mismo método de implementación utiliza VmWare para VCenter y dudo que ellos no sepan lo que hacen -
 
Sigamos en base a tu aclaración ... ¿Y si quiero simular 3000 muertes de enemigo?¿Debería entonces crear 3000 enemigos y matarlos?, ¿No existe la remota posibilidad de realizarlo con un comando? ... Mejor aún, vamos al Networking ... Como sincronizo todo un juego basado en componentes no referenciados ... 
 
Creo, en cierta forma que has interpretado mal el mensaje, y tu forma de contestar no va con tus "conocimientos" ...
 
Como tambien lo dice @lightbug, deberias corregir, no simplemente insultar.

Cita de: francoe1 date=1502377107Esto puede estar bien, o mal, dependiendo de cuántos jugadores estén dentro del juego, pero no por eso deja de ser una buena idea o solución.
   


Buen punto, mi alcance nunca fue el multiplayer pero es cierto puede resultar en catastrofe, primero porque como lo tengo yo cualquier muerte daria lugar a la llamada del unico evento, epic fail.
 
 
 
 

Cita de: lightbug date=1502377461Buen punto, mi alcance nunca fue el multiplayer pero es cierto puede resultar en catastrofe, primero porque como lo tengo yo cualquier muerte daria lugar a la llamada del unico evento, epic fail.
   
   
       
   
   
       
   


Aun así, no lo vería como un "Error"... Pero la mejor forma de pensar es que en nuestra aplicación debe existir un árbitro, alguien que diga esto si esto no... pero si pensamos en que cada objeto lleve los eventos entonces pensamos en referencias, y si tenemos 20000 objetos lanzando eventos entonces tenemos un problema, no es lo mismo llamar un evento 20000 veces que instanciar 20000 eventos y capturarlos, y si él objetos se destruye se pierde la referencia

Etiquetas: