Saltar navegación

Activa JavaScript para disfrutar de los vídeos de la Mediateca.

Primeros pasos en Unity: corrutinas - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 25 de septiembre de 2024 por Alvaro H.

99 visualizaciones

Veamos cómo crear procesos asíncronos en Unity

Descargar la transcripción

Vamos a hablar de las corrutinas, que son, para qué sirven y cómo se usan. 00:00:07
Pero antes de hacerlo voy a hablar de un concepto, que es el de la ejecución asíncrona de un script. 00:00:13
Normalmente cuando en programación ejecutamos scripts, pues lógicamente se ejecutan, pues como hemos visto, 00:00:17
según van saliendo las líneas de código. 00:00:23
Y de hecho hasta que no se termina la ejecución de una línea o de un bucle, ahí está la clave, 00:00:26
pues no sigue ejecutándose el script, lo cual nos produce bastantes limitaciones a la hora de 00:00:30
de programar ciertos comportamientos complejos. Lo voy a ejemplificar mediante 00:00:34
un código que nos ayudará a entenderlo. Voy a crear un nuevo script que no 00:00:41
necesito que esté asociado a ningún GameObject y, por tanto, me viene muy bien, como ya 00:00:49
hemos visto hasta ahora, crear un EmptyObject. Lo voy a renombrar, le voy a llamar 00:00:52
contador y le voy a añadir un componente, un script, al que le voy a llamar, por 00:00:55
ejemplo, counter, para saber que voy a crear un contador en ese texto. Sabiendo 00:01:02
que ya tengo control sobre el texto voy a hacer un ejemplo para entender por qué 00:01:07
a veces la ejecución de los scripts tiene que ser asíncrona. Vamos a poner 00:01:12
un ejemplo. Imaginemos que yo en la función start voy a crear un bucle, tal como 00:01:16
hemos aprendido, por ejemplo con un for, y le voy a decir que el texto 00:01:23
de esa user interface sea igual a n, diciéndole que ponga un texto 00:01:29
contador, dos puntos, espacio, y concateno, con lo cual eso ya es un texto, 00:01:36
aunque incluya un número entero, pero el conjunto general ya es una variable de tipo texto. 00:01:42
Entonces, ¿qué es lo que acabamos de hacer? 00:01:46
Un bucle que se va a repetir 11 veces, porque empezamos a contar por cero, 00:01:48
y en cada vuelta va a cambiar el texto y le va a decir que ponga contador seguido de el número. 00:01:52
Y una persona, digamos, un humano pensaría que lo que vamos a ver es una cuenta hacia adelante, 00:01:58
0, 1, 2, 3, 4, 5, hasta 10, pero si lo ejecuto, veremos que se produce algo. 00:02:01
Lo lanzo y ¿qué texto me aparece aquí? Mi contador es 10. De golpe. ¿Por qué ocurre esto? 00:02:05
Porque el código se ha quedado aquí dando vueltas y él no ha seguido ejecutando todo lo demás hasta que ha terminado este bucle. 00:02:13
Y cuando ha terminado ese bucle ha seguido con la ejecución. ¿Y qué valor tenía esto cuando ha terminado el bucle? 00:02:19
Pues contador igual a 10. Y claro, yo no he visto ese proceso. Así que para eso existen las corrutinas. 00:02:24
Las corrutinas existen precisamente para poder ejecutar un script mientras se continúa la ejecución de todo lo demás. 00:02:28
Es como una especie de, bueno, quédate tú ejecutando mientras yo sigo con todo el procesamiento. 00:02:37
Pero además las corrutinas nos ofrecen algo que ahora mismo necesito, que es, vale, yo quiero que te quedes ahí ejecutándote, 00:02:44
pero además necesito, pues lo que acabo de hacer, hacer un bucle, pero ese bucle que no se ejecute de golpe, 00:02:51
sino que se vaya ejecutando cada cierto tiempo, lo que sería un contador. 00:02:56
Imaginémonos que yo voy a contar 10 segundos hacia adelante, 0, 1, 2, 3, 4, 5, y cada uno tiene que durar un segundo. 00:02:59
Con lo cual, aunque eso lo podría hacer con el método update de una forma un poco rebuscada, 00:03:06
lo realmente útil es usar las corrutinas. ¿Por qué? 00:03:11
Porque aparte de ejecutarse de forma asíncrona, nos permiten meterle el parámetro de 00:03:14
y cada cuánto tiempo se ejecuta esa corrutina. 00:03:19
Vamos a ver cómo funcionan y cómo es la sintaxis. 00:03:22
lo primero que tenemos que saber de las corrutinas es que funcionan como si fuesen métodos 00:03:26
se utilizan mediante el método general de enumerator, se escribe así 00:03:30
y funcionan como un método en el sentido de que le tenemos que dar un nombre 00:03:35
por ejemplo le voy a decir cronómetro, cuidado con las tildes 00:03:38
así que si nos fijamos, esto es como si fuese un método 00:03:41
y lo tenemos que llamar, de hecho ahora me está dando un error porque me está diciendo que no estoy dándole 00:03:49
el parámetro apropiado para continuar esta corrutina, ¿y cuál es el parámetro adecuado? 00:03:54
Pues uno que siempre tendremos que poner, que es así. Se escribe yield return. Y eso lo tenemos que escribir. Y le tenemos que dar un valor. ¿Cuál? El tiempo que queremos que pase entre una vuelta y otra. 00:03:58
Si le decimos que null, directamente se ejecuta en cada fotograma. Un poco parecido al update. Pero, cuidado, esto no es un bucle. No nos confundamos. 00:04:12
esto no es como el update 00:04:21
que se ejecuta de forma permanente 00:04:24
esto se ejecutaría una vez 00:04:25
si yo lo llamo, si yo quiero 00:04:27
que haga un bucle, lo tengo que crear yo 00:04:29
por ejemplo, mediante un while 00:04:31
y while si nos recordamos 00:04:33
lo que tenemos que decirle es para 00:04:35
un parámetro 00:04:37
o una condición que mientras se dé while se va a ejecutar 00:04:39
pero si le escribimos true 00:04:42
directamente, acabo de crear un bucle infinito 00:04:43
y es en ese bucle infinito 00:04:45
donde yo le puedo decir que 00:04:48
ejecútate cada fotograma. Lo vamos a comprobar y esta vez no lo voy a mandar a la ventana del 00:04:51
texto, sino que lo voy a mandar a la consola para que lo veamos mejor. Voy a ejecutarlo, pero esto es como 00:04:57
si fuese un método. Alguien lo tiene que llamar, alguien lo tiene que ejecutar. Pues bien, para ejecutar 00:05:01
una corrutina, para que empiece a funcionar, existe el comando start corrutin. Y entre paréntesis 00:05:06
y entre comillas, porque es un nombre, le tenemos que dar el nombre de la corrutina que queremos 00:05:13
ejecutar. Así que cuando se ejecute el script, llamará la corrutina, que lo que hace es 00:05:17
un bucle infinito, en el que le he dicho que me muestre hola en la consola y además ejecute 00:05:26
cada fotograma. Vamos a ver si funciona. Lo lanzo. Y si todo va bien, ahí lo tenemos. 00:05:30
Me está diciendo hola, pero si nos fijamos, me está mandando todos esos mensajes en cada 00:05:39
fotograma. Eso está bien, pero no es lo que quiero. Además, para eso ya tenía el update. 00:05:42
Vamos a la función realmente interesante de las corrutinas, que es poder decirle, 00:05:46
espera un tiempo antes de volver a dar una vuelta. 00:05:50
En vez de decirle aquí null, le podemos crear una instancia 00:05:53
llamado waitForSeconds, por lo tanto, tenemos que llamarlo 00:05:58
mediante la instanciación de una clase llamada waitForSeconds 00:06:03
y aquí está esperando un número decimal, un float, 00:06:07
que nos dirá cuántos segundos. 00:06:11
Yo le puedo decir que uno, con la F para indicarle que es un float, 00:06:12
y eso significa que va a esperar un segundo en cada vuelta del ciclo. 00:06:15
Vamos a comprobarlo. 00:06:18
Guardo. 00:06:19
Lo lanzo, y de nuevo si todo va bien, aquí me lanzará a consola hola, igual que antes, 00:06:20
pero si nos fijamos la cadencia como la hace, efectivamente la está lanzando una vez cada 00:06:29
segundo. 00:06:33
Bien, nos vamos acercando. 00:06:34
Así que nada, ahora es echar la imaginación. 00:06:35
Voy a crear un contador, ya sabemos cómo, voy a crear una corrutina que se ejecute cada 00:06:37
segundo, y lo que voy a hacer es que ese texto que mandaba la pantalla en cada vez, en cada 00:06:42
ciclo pues lo voy a cambiar. 00:06:47
¿Por qué? 00:06:48
Por un número. 00:06:49
cero y voy a seguir avanzando. Así que, ¿cómo hacíamos bucles en los que un valor va cambiando? 00:06:50
Pues con el bucle for. Aquí, en vez de un while, voy a borrarlo para hacerlo de cero 00:06:55
y así le vamos cogiendo el tranquillo. De hecho, voy a borrar la función de update 00:07:01
porque ya no la necesito. De hecho, las corrutinas pueden sustituir a update si lo necesitamos. 00:07:05
Pues bien, voy a crear un bucle for creando una variable llamada n de número entero, 00:07:10
cuyo valor inicial es cero. Le doy una condición, es decir, mientras n sea menor o igual que 00:07:15
100, por ejemplo, pues súmale 1 a n. ¿Y qué es lo que hago? Mandar al texto, como 00:07:19
hemos visto antes, un nuevo texto, que va a ser contador, dos puntos, y a continuación 00:07:29
ahora sí, n. Y muy importante recordar, por eso me está aquí dando error, le tengo que 00:07:35
decir a mi corrutina cada cuánto tiempo se tiene que ejecutar. La sintaxis es con yel 00:07:41
return, y en este caso le voy a decir 00:07:49
new waitForSeconds 00:07:51
y lo he dicho. 00:07:53
Un segundo. 00:07:57
¿Qué tenemos ahora mismo? 00:07:59
Un contador. 00:08:01
Ahí lo tenéis. 00:08:03
Ya está. Así de sencillo. 00:08:05
Tengo que decir que 00:08:08
existe, igual que podemos 00:08:09
lanzar un contador, podemos, o sea, igual que 00:08:11
lanzamos una corrutina con el startCorroutine, también la podemos 00:08:12
parar. Es decir, si ya llega un momento en el que tenemos que detener 00:08:15
esa ejecución, pues 00:08:17
la podemos parar mediante stopCodeRoutine. 00:08:19
De hecho, 00:08:21
voy a hacer una cosa, por si alguien no lo sabe. 00:08:23
Aquí le he dicho un bucle for en el que le he dicho 00:08:25
que mientras n sea menor o igual que 100. 00:08:27
Pero ¿y si yo no quiero que pare nunca? 00:08:29
Podéis borrar esta condición. 00:08:31
Ponéis lo que hay entre los puntos y coma vacío 00:08:32
y entonces no le estamos dando una condición. 00:08:35
Se va a estar ejecutando de forma permanente. 00:08:37
¿Ok? Y similar al while. 00:08:39
Pero lo que decía, ¿y si yo quiero parar 00:08:40
en un momento dado la corrutina? 00:08:43
Pues bien, en este bucle que acabo de crear 00:08:45
yo puedo directamente decirle, oye, si n 00:08:46
es igual a 10 00:08:49
pues vamos a ser más precisos 00:08:52
si es mayor o igual que 10 00:08:54
para la corrutina 00:08:55
con el comando 00:08:59
stop corrutin 00:09:01
igual que el start 00:09:02
pasándole 00:09:03
el nombre de la corrutina 00:09:04
ahora mismo 00:09:07
lo que acabo de hacer 00:09:08
es lo mismo que he hecho antes 00:09:09
un contador que empieza en 0 00:09:10
y va avanzando 00:09:11
y que avanza cada segundo 00:09:11
pero el mismo 00:09:13
cuando llegue a 10 00:09:15
detendrá esa corrutina 00:09:16
es decir 00:09:17
detendrá ese ciclo 00:09:18
vamos a comprobarlo 00:09:19
y 10 00:09:21
bien, vale, cosas de la precisión 00:09:22
¿por qué ha ocurrido esto? 00:09:25
porque este if lo he puesto aquí 00:09:27
y si lo hubiese puesto 00:09:29
justo antes de esto 00:09:31
pues habría llegado hasta 10, no hasta 11 00:09:33
pero bueno, cosas que vamos viendo 00:09:34
pequeños bugs que van saliendo 00:09:36
vayamos un paso más allá 00:09:37
pulamos nuestras corrutinas 00:09:41
¿y si el parámetro que determina 00:09:43
cuando se ejecuta es una variable? 00:09:45
imaginemos, no sé 00:09:48
que estoy lanzando elementos 00:09:49
a mi escena, por ejemplo prefabs 00:09:51
instanciando prefabs 00:09:53
y los voy a lanzar pues cada X tiempo 00:09:54
pero ese X tiempo no es fijo 00:09:56
sino que viene determinado 00:09:58
por otros parámetros, el nivel en el que estoy 00:10:01
la velocidad a la que me muevo 00:10:03
la energía de la que 00:10:05
dispongo, en fin, una variable 00:10:07
¿podemos hacer eso? 00:10:08
como siempre que se hace una pregunta en programación 00:10:10
sí, se puede hacer 00:10:12
vamos a ver cómo, voy a borrar esto 00:10:14
¿de acuerdo? porque ahora lo que me interesa 00:10:19
es que este parámetro que ahora mismo 00:10:21
lo he dado fijo, sea ahora una variable. 00:10:23
Así que antes que nada voy a crear aquí una variable 00:10:25
de tipo serialize, para así poder acceder a ella 00:10:27
desde la 00:10:29
interfaz de Unity. Le voy a llamar speed 00:10:31
a la velocidad a la que se mueve. 00:10:33
Y entonces, donde antes 00:10:36
decía que se ejecutase cada segundo, 00:10:37
le voy a poner aquí speed. 00:10:39
Eso significa que ahora mi contador 00:10:41
voy a parar la ejecución 00:10:43
ahora mi contador depende 00:10:46
de esta variable que tengo aquí a disposición. 00:10:48
De hecho, ahora mismo, si lanzo 00:10:51
la corrutina, como esa variable vale 0 00:10:52
pues 00:10:54
se ejecuta cada fotograma 00:10:56
vale 00:10:59
es como si le hubiese dado un return 00:11:00
como hemos dicho antes 00:11:02
pero si le doy un valor de 1 00:11:03
ahora mismo si lo ejecuto 00:11:06
vemos que la corrutina 00:11:09
se ejecuta cada segundo 00:11:12
pero no solo eso, sino que además 00:11:13
mientras dure la ejecución voy a modificar el parámetro 00:11:14
de la velocidad 00:11:17
le voy a decir que se ejecute cada medio segundo 00:11:18
ahí está 00:11:21
o cada décima de segundo 00:11:21
ahí está 00:11:24
o cada dos segundos 00:11:25
y ahora mi contador se ejecuta 00:11:26
cada segundo 00:11:31
cada dos segundos 00:11:31
Idioma/s:
es
Autor/es:
Álvaro Holguera
Subido por:
Alvaro H.
Licencia:
Reconocimiento - No comercial - Sin obra derivada
Visualizaciones:
99
Fecha:
25 de septiembre de 2024 - 1:28
Visibilidad:
Público
Centro:
CFP JOSÉ LUIS GARCI
Duración:
11′ 33″
Relación de aspecto:
1.78:1
Resolución:
1280x720 píxeles
Tamaño:
265.10 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid