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.
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.
Buenas, si necesitas algo que se use en todas las escenas lo que se usa es el "DontDestoryOnLoad (https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html)".
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.
Cita de: AlterKZero date=1538401604Por 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 (@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.
Cita de: AlterKZero date=1538401604PD: 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 (https://docs.unity3d.com/Manual/class-MonoManager.html)
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
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...
Cita de: Igor date=1538474290hola, 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.
Cita de: Ufita date=1538477851
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.
si, sorry, no me salia el nombre.... y he usado la palabra que me parecia mas similar...
Antes que todo agradecer a @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.
Cita de: AlterKZero date=1538577882- 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 destro*** either. " Cita de: AlterKZero date=1538577882- 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 ?
Cita de: lightbug date=1538583084Buena 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 destro*** 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é.
Cita de: AlterKZero date=1538590314lo 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:
(http://silverhuber.com/Unity/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).
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...
Cita de: AlterKZero date=1538577882Antes que todo agradecer a @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,
Cita de: Igor date=1538642597
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. Cita de: lightbug date=1538604464Que "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:
(http://silverhuber.com/Unity/Dont.png) (http://silverhuber.com/Unity/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. Cita de: Ufita date=1538649879Bueno 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.