Jump to content
Sign in to follow this  
TheShopKeeper

Duda sobre el trabajo con Scripts

Recommended Posts

Disculpen por el Título tan "poco descriptivo" es que la duda no sabría como resumirla en un título.

En Unity es la primera vez que trabajo orientado a objetos, por lo cual para mi es una nueva experiencia.

Anteriormente trabajaba en RPG Maker, donde los scripts se ejecutaban todos a la misma vez que el motor, por lo cual si por ejemplo: creaba un script de sistema de Día y Noche para un RPG, lo único que tenía que hacer era introducir el script y llamarlo para operar con el para que fuera necesario, pero este script siempre estaba funcionando, sin importar la scene en que me encontraba.
ScriptEditor.png

Ahora mi duda es la siguiente. Por los tutoriales que leído y he visto, nunca he encontrado a alguien trabajando de esta forma, o sea, la manera de crear un script y que este opere "siempre" dentro del juego, para llamarlo o trabajar con el siempre que sea necesario. Normalmente los tutoriales que leo son para proyectos pequeños, que contienen una scene o 5, pero y si tengo 150 scenes?

A ver, mi objetivo en realidad es hacer en Unity un sistema de día y noche para un RPG. La duda es que si existe alguna forma de que Unity cargue todo el tiempo con este script, porque creo que no es muy práctico añadir el script a cada una de las scenes, porque por ejemplo cuando lleve 200 scenes, tener el mismo script 200 veces asignado lo veo un poco raro. Además que lo veo un poco más complejo a la hora de trabajar con él, porque tendría que estar guardando las variables del tiempo cada vez que cambie de scene.

¿Algún consejo sobre esto?

Saludos y disculpen por extenderme tanto es que quería ser lo más explicativo posible.

PD: A mi se me había ocurrido trabajar con el Script Execution Order, pero me gustaría conocer vuestro criterio antes de hacer algo que luego me traiga muchos problemas o que se podía hacer de otra forma.
execution order.png

Share this post


Link to post
Share on other sites

Buenas, si necesitas algo que se use en todas las escenas lo que se usa es el "DontDestoryOnLoad".  

Imagino que para hacer un ciclo día/noche como comentas deberías obtener los objetos de pantalla con algún find, o algo por el estilo para mover la luz, etc.  Porque obviamente no puedes asignar a cada escena el script. 

Mira por ese lado a ver si te vale. 

 

  • Like 2

Share this post


Link to post
Share on other sites
5 hours ago, AlterKZero said:

Por los tutoriales que leído y he visto, nunca he encontrado a alguien trabajando de esta forma, o sea, la manera de crear un script y que este opere "siempre" dentro del juego, para llamarlo o trabajar con el siempre que sea necesario. Normalmente los tutoriales que leo son para proyectos pequeños, que contienen una scene o 5, pero y si tengo 150 scenes?

¿Algún consejo sobre esto?

Bueno una lección valiosa -> nunca aprender de tutoriales, los tutoriales son para reforzar o ver como alguien aplica lo teórico, no para aprender el concepto de algo, en este caso el de script.

  • Scene 1 ------ GameObject 1  --------- Componente 1
  •                                                   --------- Componente 2
  •                                                   --------- Componente 3          
  •                ------ GameObject 2  --------- Componente 1
  •                                                   --------- Componente 2
  •                                                   --------- Componente 3    

             ....

  • Scene 2 ------ GameObject 1  --------- Componente 1
  •                                                   --------- Componente 2
  •                                                   --------- Componente 3          
  •                 ------ GameObject 2  --------- Componente 1
  •                                                   --------- Componente 2
  •                                                   --------- Componente 3    

Un script corresponde a un componente (Monobehaviour -> Behaviour -> Component ), es decir que si matás a la Scene chau gameobjects, chau componentes y todo lo que siga, salvo que hagas como dice @Ufita de avisar que antes de descargar una escena y cargar una nueva el gameObject del argumento no sea borrado, en concecuencia sus componentes siguen vivos, osea sus scripts siguen vivos.

También ya que está, es muy común confundir script con código en general en resumen vos podés crear un "C# script", esto va a crear un monobehaviour por defecto pero podés transformar ese monobehaviour en una clase cualquiera de C# que podés usar como se te cante, o en varias clases, o interfaces, etc.

Un script (por lo menos en motores modernos y en Unity) hace lo que dice su nombre, es un "guión", cada Actor (o GameObject) es inerte sin él, o por lo menos alguien lo debe tener para que se actulice o que actualice a otros actores, sin un script no se da la interacción en tiempo real con nada, no se como será en RPGMaker. El alcance que vos le des a un script es problema tuyo, querés que arranque el motor y el script esté hasta el Application.Quit() , totalmente realizable. Querés que esté activado durando 1 ms, también.

5 hours ago, AlterKZero said:

PD: A mi se me había ocurrido trabajar con el Script Execution Order, pero me gustaría conocer vuestro criterio antes de hacer algo que luego me traiga muchos problemas o que se podía hacer de otra forma.

Execution Order

Todo "script" (acordate de los monobehaviours) será actualizada en un orden:

  • Start d script 1
  • Start d script 2
  • Start d script 3
  • ...
  • Update d script 1
  • Update d script 2
  • Update d script 3
  • ...
  • LateUpdate d script 1
  • LateUpdate d script 2
  • LateUpdate d script 3

Ponele que querés que el script 1 evalue la posición final del resto de los objetos y haga algo, entonces necesitas que sea el ultimo de la serie de Updates (ya que por como está el tipo hace lo suyo y luego script 2, 3 , etc siguen modificandose (quizás) ). Podés o mandarlo a LateUpdate y listo, pero, Que pasa si script 2 y 3 también tienen mensajes de LateUpdate y también se mueven? -> tamo en la misma que antes. Entonces te metés en Execution Order y agregas el "script 1" después del default Time.

Por el defaultTime se refiere a "lo actualizo cuando quiera", cosa que puede que no te agrade:   All scripts not in the dialog execute in the default time slot in arbitrary order.

Entonces luego de acomodar como dije arriba te queda:

  • Start d script 2
  • Start d script 3
  • Start d script 1
  • ...
  • Update d script 2
  • Update d script 3
  • Update d script 1
  • ...
  • LateUpdate d script 2
  • LateUpdate d script 3
  • LateUpdate d script 1

 

Es muy útil.

Saludos

 

  • Like 2

Share this post


Link to post
Share on other sites

hola, monoBehabiour requiere estarDentro/serUnComponente de un GameObject.... cuando cargues una escena nueva el objeto con el script desaparecera...

a no ser que uses "dont destroy on load"...

tambien puedes crear una classe estatica, que no requiera estar en escena.... sin que "descienda" de monoBehabiour.... y funcionara como dices, estara presente en todas las esecenas.... 

yo uso ese metodo para guardar variables globales como puntuacion total... el oro que tienes... o ese tipo de cosas...

  • Like 1

Share this post


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

hola, monoBehabiour requiere estarDentro/serUnComponente de un GameObject.... cuando cargues una escena nueva el objeto con el script desaparecera...

a no ser que uses "dont destroy on load"...

tambien puedes crear una classe estatica, que no requiera estar en escena.... sin que "descienda" de monoBehabiour.... y funcionara como dices, estara presente en todas las esecenas.... 

yo uso ese metodo para guardar variables globales como puntuacion total... el oro que tienes... o ese tipo de cosas...

 

Solo por aclarar una cosa, el "descienda" se dice Herede de... estamos hablando de un lenguaje orientado a objetos, así que esa característica se le llama herencia. Obviamente lo has dicho bien pero para que queden claros conceptos básicos y llamemos a las cosas por su nombre. :4_joy:

  • Like 1

Share this post


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

 

Solo por aclarar una cosa, el "descienda" se dice Herede de... estamos hablando de un lenguaje orientado a objetos, así que esa característica se le llama herencia. Obviamente lo has dicho bien pero para que queden claros conceptos básicos y llamemos a las cosas por su nombre. :4_joy:

si, sorry, no me salia el nombre.... y he usado la palabra que me parecia mas similar...:7_sweat_smile:

  • Like 1

Share this post


Link to post
Share on other sites

Antes que todo agradecer a @Igor @lightbug @ufita   por contestar tan rápido.

@igor , me gusta tu idea de trabajar con una clase estática, pero tengo una duda. ¿Cómo le digo a Unity que lea esa clase? ¿Tendría que añadirla a algún lado en específico o asignarla a algún Objeto dentro de una escena? (No se si he escrito la pregunta correctamente, como siempre en Unity he trabajado con Monovehavour no se como hacer que trabaje una clase que yo vaya a crear.

@lightbug @ufita , hasta ahora lo que entendí que hace el DontDestroyOnLoad es lo siguiente, al asignarlo a un objeto, cuando cambias de escena este no se destruye y puedes continuar trabajando con él. Pero me vinieron unas cuantas dudas a la mente, que cuando termine de trabajar quiero ver si las pongo a prueba, como por ejemplo:

- Si yo tengo en la Hierarchy un objeto llamado "Árboles" y dentro de "Árboles" hay 100 objetos "árbol", si yo le asigno el DontDestroyOnLoad solo a "Árboles", ¿los hijos se quedan o se borran?

- Si tengo un objeto "cubo" y le asigno un movimiento sencillo con las flechas y el DontDestroyOnLoad, al cambiar de scene, el "cubo" aparecerá en la scena nueva que cargué o el cubo no se va a ver porque está por decirlo de cierta forma "en el limbo"

Ya todo esto lo probaré luego. Gracias una vez más. Saludos.

 

Share this post


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

- Si yo tengo en la Hierarchy un objeto llamado "Árboles" y dentro de "Árboles" hay 100 objetos "árbol", si yo le asigno el DontDestroyOnLoad solo a "Árboles", ¿los hijos se quedan o se borran?

Buena pregunta? respuesta fácil -> probá :) .... respuesta improvisada mía -> un gameObject está definido por sus hijos, cuando instancias un prefab se instancia todo, hijos, nietos, etc así que supongo que sobrevive todo.

 

Ah mirá -->" If the object is a component or game object then its entire transform hierarchy will not be destroyed either. "

1 hour ago, AlterKZero said:

- Si tengo un objeto "cubo" y le asigno un movimiento sencillo con las flechas y el DontDestroyOnLoad, al cambiar de scene, el "cubo" aparecerá en la scena nueva que cargué o el cubo no se va a ver porque está por decirlo de cierta forma "en el limbo"

Si tiene DDOL, mejor dicho, si alguien llama a DDOL y le pasa el cubo de argumento este sobrevivirá. No se a que te referís con que quede en el limbo ?

  • Like 1

Share this post


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

Buena pregunta? respuesta fácil -> probá :) .... respuesta improvisada mía -> un gameObject está definido por sus hijos, cuando instancias un prefab se instancia todo, hijos, nietos, etc así que supongo que sobrevive todo.

 

Ah mirá -->" If the object is a component or game object then its entire transform hierarchy will not be destroyed either. "

Si tiene DDOL, mejor dicho, si alguien llama a DDOL y le pasa el cubo de argumento este sobrevivirá. No se a que te referís con que quede en el limbo ?

Tengamos en cuenta una cosa, el Cubo está en la escena 1, a este cubo le pondré el DontDestroyOnLoad y un sistema de movimiento. Al cambiar de escena la propiedad de moverse del cubo se mantienen vivas, lo que no se si este se mueve en una "escena 1" que ya fue borrada (o sea, el limbo) o si se mueve en la nueva escena. De todas formas ya probaré.

Share this post


Link to post
Share on other sites
3 hours ago, AlterKZero said:

lo que no se si este se mueve en una "escena 1" que ya fue borrada (o sea, el limbo) o si se mueve en la nueva escena. De todas formas ya probaré.

Que "se mueva" corresponde parte a un behaviour propio que le asignaste al cubo, a la escena no le interesa nada de lo que pasa por ella, lo mismo bidireccionalmente, vos te movés sin importar donde estés. No entiendo el concepto del Limbo que planteas ... por eso arriba puse GameObject -> Componentes , si vos salvás al GO el resto también se salva, no es una copia ni un clon, es el mismo gameObject que antes con todas sus variables y demás, misma posición, misma rotación, etc, incluso si chequeas su ID seguro sea el mismo antes y despues de cargar la escena (los IDs cambian cada vez que das "Play"), (aunque puede ser que Unity haga algo raro ... aunque no creo), lo único en particular es que el cubo está colado en la escena nueva, es un polizón. El limbo ese que mencionas no existe (o por lo menos si entiendo a lo que te referís), Unity entiende de escena/escenas actuales (osea GO actuales), el resto se borra de memoria, por eso es importantellamar a DDOL.

Si te fijas en el Hierarchy aparece un "Dont Destroy On Load" en la "forma" de una escena aparte:

Dont.png

es exactamente como lo interpreta Unity, es como les crea su propia escena inventada para que ellos jueguen, no los integra de lleno a las nuevas escenas. Posibles problemas que aparezcan quizás esten a la hora de usar un Find, que busca elementos de la escena, y si pasaste un GO a DDOL puede que quede aislado a la hora de usar el FInd (o por lo menos yo tenía estos problemas, ahora no se como se maneja esto puede que haya cambiado).

  • Like 1

Share this post


Link to post
Share on other sites
public static class VariablesGlobales {
   public static int puntuacion = 0;
   public static string playerName = "pepito";

}

 

y desde cualquier script las llamas asi: (ejemplos)

int puntos = VariablesGlobales.puntuacion;

VariablesGlovales.puntuacion += 100;

//etc...

 

  • Like 1

Share this post


Link to post
Share on other sites
19 hours ago, AlterKZero said:

Antes que todo agradecer a @Igor @lightbug @ufita   por contestar tan rápido.

@igor , me gusta tu idea de trabajar con una clase estática, pero tengo una duda. ¿Cómo le digo a Unity que lea esa clase? ¿Tendría que añadirla a algún lado en específico o asignarla a algún Objeto dentro de una escena? (No se si he escrito la pregunta correctamente, como siempre en Unity he trabajado con Monovehavour no se como hacer que trabaje una clase que yo vaya a crear.

@lightbug @ufita , hasta ahora lo que entendí que hace el DontDestroyOnLoad es lo siguiente, al asignarlo a un objeto, cuando cambias de escena este no se destruye y puedes continuar trabajando con él. Pero me vinieron unas cuantas dudas a la mente, que cuando termine de trabajar quiero ver si las pongo a prueba, como por ejemplo:

- Si yo tengo en la Hierarchy un objeto llamado "Árboles" y dentro de "Árboles" hay 100 objetos "árbol", si yo le asigno el DontDestroyOnLoad solo a "Árboles", ¿los hijos se quedan o se borran?

- Si tengo un objeto "cubo" y le asigno un movimiento sencillo con las flechas y el DontDestroyOnLoad, al cambiar de scene, el "cubo" aparecerá en la scena nueva que cargué o el cubo no se va a ver porque está por decirlo de cierta forma "en el limbo"

Ya todo esto lo probaré luego. Gracias una vez más. Saludos.

 

Bueno como ya te han comentado lo mejor es probar, aunque sinceramente no llego a entender tu necesidad, ya sé que es un ejemplo pero no veo la razón para llevar un cubo o 100 arboles de una escena a la otra. 

De todos modos, al usar DontDestroyOnload, lo que haces, como ya te han dicho, es decirle a ese GO que no se debe destruir por lo tanto le indicas que es independiente de la escena. El "problema" que se te plantea es pensar que los GO son hijos de una escena y por lo tanto se pierden al cambiar, o quedan en el "limbo", justamente lo que buscas con DontDestroyOnload es decirle "tú no dependes de ninguna escena, eres único y debes existir siempre".  

Igual como te decía lo mejor es probarlo, yo no entiendo qué quieres hacer, el DontDestroyOnload lo he usado para mantener datos necesarios en todas las escenas,  por ejemplo una selección de personaje, pero no el GO entero, es decir, no un modelo 3d (cubo) y sus posiciones en pantalla, etc. etc. sino más bien una variable con valor que luego utilizo más adelante. 

Saludos, 

 

  • Like 1

Share this post


Link to post
Share on other sites
On 10/4/2018 at 4:43 AM, Igor said:

public static class VariablesGlobales {
   public static int puntuacion = 0;
   public static string playerName = "pepito";

}

 

y desde cualquier script las llamas asi: (ejemplos)


int puntos = VariablesGlobales.puntuacion;

VariablesGlovales.puntuacion += 100;

//etc...

 

Perfecto, muchas gracias.

 

On 10/3/2018 at 6:07 PM, lightbug said:

Que "se mueva" corresponde parte a un behaviour propio que le asignaste al cubo, a la escena no le interesa nada de lo que pasa por ella, lo mismo bidireccionalmente, vos te movés sin importar donde estés. No entiendo el concepto del Limbo que planteas ... por eso arriba puse GameObject -> Componentes , si vos salvás al GO el resto también se salva, no es una copia ni un clon, es el mismo gameObject que antes con todas sus variables y demás, misma posición, misma rotación, etc, incluso si chequeas su ID seguro sea el mismo antes y despues de cargar la escena (los IDs cambian cada vez que das "Play"), (aunque puede ser que Unity haga algo raro ... aunque no creo), lo único en particular es que el cubo está colado en la escena nueva, es un polizón. El limbo ese que mencionas no existe (o por lo menos si entiendo a lo que te referís), Unity entiende de escena/escenas actuales (osea GO actuales), el resto se borra de memoria, por eso es importantellamar a DDOL.

Si te fijas en el Hierarchy aparece un "Dont Destroy On Load" en la "forma" de una escena aparte:

Dont.png

es exactamente como lo interpreta Unity, es como les crea su propia escena inventada para que ellos jueguen, no los integra de lleno a las nuevas escenas. Posibles problemas que aparezcan quizás esten a la hora de usar un Find, que busca elementos de la escena, y si pasaste un GO a DDOL puede que quede aislado a la hora de usar el FInd (o por lo menos yo tenía estos problemas, ahora no se como se maneja esto puede que haya cambiado).

Hasta que no lo puse en práctica no comprendí su funcionamiento. Me parece excelente el uso del DDOL para las cosas indispensables.

 

On 10/4/2018 at 6:44 AM, Ufita said:

Bueno como ya te han comentado lo mejor es probar, aunque sinceramente no llego a entender tu necesidad, ya sé que es un ejemplo pero no veo la razón para llevar un cubo o 100 arboles de una escena a la otra. 

De todos modos, al usar DontDestroyOnload, lo que haces, como ya te han dicho, es decirle a ese GO que no se debe destruir por lo tanto le indicas que es independiente de la escena. El "problema" que se te plantea es pensar que los GO son hijos de una escena y por lo tanto se pierden al cambiar, o quedan en el "limbo", justamente lo que buscas con DontDestroyOnload es decirle "tú no dependes de ninguna escena, eres único y debes existir siempre".  

Igual como te decía lo mejor es probarlo, yo no entiendo qué quieres hacer, el DontDestroyOnload lo he usado para mantener datos necesarios en todas las escenas,  por ejemplo una selección de personaje, pero no el GO entero, es decir, no un modelo 3d (cubo) y sus posiciones en pantalla, etc. etc. sino más bien una variable con valor que luego utilizo más adelante. 

Saludos, 

 

Lo de los árboles era solo un ejemplo, pero gracias a ustedes logré encaminarme en lo que quería hacer. Saludos.

Share this post


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

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...