Unity duda inicialización de componentes

WBIndieGame

A la hora de trabajar con Unity, veo tanto en foros, videotutoriales, como cursos pagados por mi bolsillo, de gente que está certificada por Unity (vamos que no son principiantes en esto) un comportamiento que me resulta peculiar.

Supongamos que dispongo de un GameObject en el editor, y ese GameObject consta de varios componentes, por ejemplo, supongamos que tiene asociado un RigidBody.

Resulta que se realiza un script para hacer X tarea y que va a asociado al GameObject mencionado previamente, y va necesitar interactuar con el componente Rigidbody del GameObject.

El comportamiento peculiar, es que veo que en muchos casos, definen una variable pública de tipo Rigidbody con nombre "rb" y que nunca inicializan, trabajan con ella, guardan el script.

Asocian el script al GameObject como un segundo componente, y arrastran el componente RigidBody a la variable rb del componente script del GameObject.

Yo no lo hago así.

En mi caso, hago exactamente lo mismo que ellos al definir el script, pero, si lo inicializo mediante código, para ello, utilizo una función del tipo:

void Awake{
    rb = this.GetComponent<RigidBody>()
}

De esa manera no tengo que arrastrar el componente desde el editor y entiendo que tengo un script autoconfigurable.

¿Es mejor mi manera de hacerlo, o la otra tiene algún sentido?

Otra aspecto de interés, es que veo que mucha gente cuando necesita obtener un componente en un script para hacer algo con el, utiliza con frecuencia el GetComponent<TipoComponente>().

Me parece un error cuando lo utilizan varias veces, es decir, en la linea 4 del código usas GetComponent<X>() y en la línea 18 usas GetComponent<X>() de nuevo, porque si vas a necesitar un componente, puedes ejecutar ese GetComponent en el Awake y almacenarlo en una variable para tenerlo accesible si vas a usarlo en otras ocasiones.

totespare

A efectos prácticos yo diría que ambas maneras funcionan correctamente. Habrá diferencias por debajo en cuanto a cómo obtiene la referencia del componente al pasarsela por el editor en comparación a si haces tú el getcomponent, pero yo creo que nada especialmente importante. Si haces el gercomponent, el riesgo que tienes es olvidarte de aladir ese compokente al gameobject. Si lo haces por editor, el riesgo es olvidarte de arrastrarlo en el editor.

Y lo segundo que comentas, efectivamente es mejor cachear componentes a hacer todo el rato llamadas al getcomponent.

1
B

Primera parte:

Realmente da un poco igual cual uses, como bien dices es cuestión de gusto. En mi caso, uso las dos versiones.
Creo variables publicas para elementos que van a ser fijos en una escena o en un componente. Por ejemplo en una UI, un botón de comenzar, el texto que tiene para ser traducido, paneles que se muestran u ocultan.

En cambio, uso GetComponent<T> para elementos que pueden estar o no, como buffs, debuffs, estados, o componentes que puedo añadir durante ejecución, que durante el start no se encuentran o en el awake pero luego voy a incluir.

Segunda parte:
Para qué quieres almacenar algo que vas a usar 1 segundo? 2 segundos? y luego ya hasta que lo necesites de nuevo?
Hay variables que se utilizan para un momento puntual, tenerlas como pública aumenta el espacio usado, que si es una sola no pasa nada pero siendo 1000 variables de 1000 objetos. Y 2 variables? 3?

Al final es saber que cosas puedes y debes almacenar y cuales no.

3
B

Cachear solo lo veo para temas de rendimiento en loops o para dejar el código más limpio. Si son dos llamadas puntuales fuera de loops "lo veo ni fú ni fá... ni mal ni bien".

En cuanto a asignar desde el editor al script... me gusta evitar hacerlo con contenedores (GameObject ) y componentes. A la larga en producción acaba dando problemas del tipo "asignaciones perdidas por fallos del editor" y si no tienes copia a mano es un coñazo.

2
B

@WBIndieGame me suena que empezaste algún proyecto por aquí... ¿llegaste a terminar algo?

1 1 respuesta
Jastro

tenia un juego de tanques no? me suena

2 2 respuestas
B

#6 lo miro y son tanques y naves... están visibles en su cuenta, pero prefiero hacer la pregunta aquí antes de revivir devlogs de ultratumba para consultar xD

WBIndieGame

#5 Hola,

Si, empecé con un demigrante juego de tanques, pero con el que aprendí muchísimo (de los miles de errores que cometí).

Y después me hice uno de naves del que logré hacer varias misiones.

En mis ratos libres he hecho alguna cosa pero a una escala mucho menor.

Cuando tenga más tiempo libre, igual me animo a hacer un proyecto más grande.

WBIndieGame

#6 Eso es, empecé con ese, luego hice uno de naves

1
deliTa_

Hola.
Primera parte, recuperar el componente en el awake no está mal, que por cierto te puedes ahorrar el "this." en esa sentencia, pero en unity está demostrado que la forma mas eficiente para recuperar componentes/referencias es haciendo la variable pública y asignándosela desde el inspector, no hay una diferencia abismal de rendimiento en comparación con el GetComponent, pero sigue siendo algo mas ligero hacerlo asignándolo (siempre que se pueda)

Sobre la segunda parte es lo que te han comentado, si vas a usarlo 2 veces de forma puntual no hace falta variable, otra cosa seria que estuvieras constantemente recuperando el componente en un bucle o cada x frames.

1

Usuarios habituales