Duda tags Unity

VriejElBardo

Hola a todos!
Estoy aprendiendo a desarrollar juegos con Unity (soy muy novato) y ahora mismo estoy haciendo uno muy muy simple que consiste únicamente en explotar burbujas de colores. La cuestión es que tengo todo el código ya funcionando a excepción de un último método:
Durante un tiempo determinado, el juego te indicará de qué color son las burbujas que debes hacer explotar, de modo que si lo haces correctamente, sumarás puntos y, si explotas burbujas de otro color, los restarás.
Entiendo que debe hacerse bajo la estructura del "gameobject.comparetag" pero, como digo, soy muy principiante y por mucho que reviso la documentación de Unity no consigo descubrir cuál es el código correcto.
¿Podéis ayudarme, por favor?

Muchas gracias de antemano!

Hukha

A ver, antes de nada tienes que saber que usar los tags de Unity es una mala manera de implementar casi cualquier cosa. (Al estar empezando no voy a entrar en mas detalles, pero deberías saberlo)

Ahora bien, los GameObjects pueden tener asignado un tag, en tu ejemplo entiendo que quieres usarlo para saber de qué color es cada burbuja, con lo que deberías asignarle a cada burbuja el tag de su color. (Link de cómo crear tags)

El método que comentas (CompareTag) solamente devuelve verdadero o falso dependiendo de si el GameObject tiene el tag que pasas o no.
Estas dos lineas serían equivalentes:

if (other.gameObject.CompareTag("Player"))
{
     //Do things
}
if (other.gameObject.tag == "Player")
{
     //Do things
}
1 3 respuestas
VriejElBardo

#2 Muchas gracias por responder. He probado lo indicado pero sigue sin funcionar. Independientemente del color "tageado" únicamente suma a pesar de que el método también indica la resta. Seguro que es una tontería incluso a nivel de configuración, pero no doy con la clave... mi código es éste:

       if (controlJuego.isGameActive)
        {
            Destroy(gameObject);
            if (gameObject.tag == "Rojo")
            {
                controlJuego.ActualizarMarcador(valorPuntos);
                controlJuego.TiempoRestante(valorTiempo);
            }
            else
            {
                controlJuego.RestarMarcador(valorPuntos);
                controlJuego.RestarTiempo(valorTiempo);
            }
            
}
2 respuestas
Hukha

#3 Sin saber qué hace tu código poco más puedo aportar.
Para que tengas más información prueba esto y mira la consola:

if (controlJuego.isGameActive)
{
            if (gameObject.tag == "Rojo")
            {
                Debug.Log("El tag es rojo, actualizando marcador...");
                controlJuego.ActualizarMarcador(valorPuntos);
                controlJuego.TiempoRestante(valorTiempo);
            }
            else
            {
                Debug.Log(gameObject.tag + ", restando...");
                controlJuego.RestarMarcador(valorPuntos);
                controlJuego.RestarTiempo(valorTiempo);
            }
            Destroy(gameObject);
}
1 1 respuesta
kesada7

Tienes un rigidbody atachado en al menos uno de los 2 gameobjects que estás intentando collisionar?

1 1 respuesta
VriejElBardo

#5 efectivamente! Cada uno de los prefabs de las burbujas tiene su respectivo RB.

#4 perfecto Hukha muchas gracias. Justo ahora estoy actualizando una nueva versión de Unity así que cuando termine, lo pruebo. En cuanto a lo del código, no lo pongo porque me sabe mal hacer spam. Ya os estoy robando tiempo suficiente xD

1 respuesta
kesada7

#6 Mira que si estás usando rigidbody 3d no estés usando los OnTriggerEnter2D y viceversa, no sé es que sin más info puede ser cualquier cosa. Lo normal es hagas debug con el IDE que estés usando para ver donde deja de entrar o almenos usar los logs.debug como te ha puesto arriba Hukha pero incluso antes porque estás seguro de que las colisiones te las está detectando? O no sé si estás usando colisiones o el que pero llega a entrar en el

 if (controlJuego.isGameActive)

?
Si entra después haz un

Debug.Log("El tag es " + gameObject.tag);

y a ver que te dice el log que tag detecta

1 1 respuesta
totespare

#3 no se hasta que punto se queda cacheado el tag de un objeto que destruyes, se que tarda minimo un frame, pero por si acaso baja el destroy abajo, después del else

1 1 respuesta
VriejElBardo

De nuevo gracias por las respuestas! #8 pues lo cierto es que llegó a pasarse esa idea por mi cabeza, así que hice la prueba poniendo un destroy dentro tanto del if como del else, pero el resultado fue el mismo. (Decir también que tal y como os lo he pasado, haciendo el Destroy primero, aunque el gameobject desaparezca las líneas de sumar puntos y actualizar tiempo se ejecutan correctamente.
De todos modos probaré lo que me indicas, muchas gracias!

#7 pues ahora que lo dices... estoy usando el método OnMouseDown que ya directamente recoge el click del mouse... y que no sea que por defecto recoja 3D cuando mis Rigidbody son 2D. En cuanto a los Debug.Log no llega ni a imprimirlos por pantalla, así que el fallo debe estar antes de eso tal y como decís.

Esta tarde en cuanto salga del trabajo me pongo a ello.

PD: como he dicho me sabe mal spamear tanto, pero si quisieseis/necesitaseis el código entero, os lo paso sin problemas.

1 1 respuesta
Jastro

#9 no te cortes, este foro es para hacer spam y solicitar ayuda.

Aprovecha que tienes unos cuantos por aqui que saben de Unity

1
PaulVaso

#2 que se debería de utilizar en vez de tags? Layers tiene mejor rendimiento?

Pregunto por qué soy un noob

1 respuesta
puntocom

#11 En general no se recomienda usar tags por varios motivos. Lo más típico es porque no son muy eficientes (que probablemente en la mayoría de casos es bastante irrelevante pero bueno).

El principal problema que le veo al usar tags, es que muy fácil tener problemas a la hora de escribir tu código. Por ejemplo cuando comparas un tag, estás comparando un string y en tu código es imposible de saber si esto va a conducir a algún tipo de error en la ejecución.

Una alternativa es utilizar componentes (clases, interfaces) o enums, de manera que trabajas con cosas que por no enrollarme mucho, digamos que te van a dar más seguridad de que todo va a salir bien. Por ejemplo comparar el tag "Enemy" podría funcionar o no, pero trabajar directamente con la clase "Enemy" o la interfaz "ICanBeDamaged" te quitará de muchos problemas, simplifica tu código y es menos propenso a problemas y no es tan unidimensional como los tags (ese es otro problema, un objeto solo puede tener un tag, lo cual puede ser bastante limitante).

3 1 respuesta
totespare

Otra opción es simplemente buscar una variable tipo enum en un componente concreto. Si tienes un prefab para las burbujas, y tienes varios tipos de burbuja, puedes meter un script al prefab, el cual tenga una variable publica (un enum) en el que le setees tú el tipo de burbuja que es. Luego simplemente coges el componente (el script) de la burbuja que has petado y preguntas por ese enum de antes, y listo. Hay muchas maneras :)

3 1 respuesta
PaulVaso

#12 #13

Muchas gracias por vuestras respuestas, es lo que había leído después de la respuesta de #2, me puse a investigar alternativas y muchos utilizaban interfaces, scripts etc. pero no sabía si era eficiente o una buena práctica.

Y qué opináis respecto TryGetComponent<Script>(out var nomVariable) ?

1 respuesta
totespare

#14 en proyectos de este estilo no vas a notar la diferencia entre una forma u otra, cuando tengas algo mas grande y necesites mejor performance entonces ya mirate qué es lo más eficiente de todo. Ese try get component será lo mismo que un GetComponent<Script> pero ya te lo guarda en una variable y te devuelve un bool. No creo que haya mucha diferencia con hacerlo a mano con el get component, comprobando si es null o no etc

VriejElBardo

Nada gente, que no hay forma... Ni siquiera me imprime los mensajes en consola.
Os paso los dos scripts que tengo, uno para el control del juego en general y otro para las burbujas en sí, a ver si me dais un atisbo de luz...

Control de Juego
Burbujas

Por cierto, este finde está siendo la Indie Dev Day en Barcelona. ¿Alguien por allí?

2 respuestas
Hukha

#16 A ver, tampoco se cual es el feedback.
Si el objeto se destruye y no hay ningún log solo puede ser por el OnTriggerEnter2D().
Si por el contrario no sucede nada es por que no se llama el OnMouseDown() o una de esas condiciones no pasa.

Llegados a este punto te sale mejor usar el debugger

2
totespare

#16 no veo ningún log en el código que has pasado, dónde dices que debería sacar mensajes por consola? Y bueno, has dicho que estas empezando y tal, así que no se si has debuggeado alguna vez con visual studio (o el que uses), pero prueba a poner breakpoints y a comprobar el flujo del código, y ve tirando del hilo.

1

Usuarios habituales

  • totespare
  • Hukha
  • VriejElBardo
  • PaulVaso
  • puntocom
  • Jastro
  • kesada7