Tela marinera... Tengo que verme los vídeos otra vez con una libreta porque son cosas muy importantes y creo que hacemos mal por costumbre. ¡Gracias Dani!
Nos pasa a todos, y me incluyo, cuando llevas años haciendo algo de cierta forma te cuesta mucho cambiarlo por alguien diga "es mejor", y muchas veces ocurre que ni nos enteramos de la actualización y seguimos a la nuestra xD
A buenas horas encuentro esto. Soy diseñador gráfico y hago juegos en mi timepo libre, he aprendido a programar con RUclips y Google. En unas semanas sacaré mi primer juego en Steam y sí, mi código es un caos. Cada vez q quiero cambiar o añadir cosas tengo que modificar varios scripts de 1,000 o 2,000 lineas >.< Justo hace un par de días he aprendido a cambiar todos los callback de Playfab por Task. Ojalá supiese controlar todas estas cosas. Buen vídeo.
Hey muchas gracias por compartir tu conocimiento, me parece excelente video y con mas contenido del esperado (el cual es genial). De cierta forma, considero que hizo falta hablar de los cancellation token ya que los threads no son controlados por el UnitySynchronizationToken sino por el default del lenguaje.
Miento. Despues de seguir investigando, creo que los metodos asincronicos creados por los usuarios corren en el main thread debido al UnitySynchronizationContext. Sin embargo este se puede remplazar para correr en otros threads. Estoy en lo correcto, cierto?
Hola! Sí, van en el hilo peincipal pero se puede hacer que corra en paralelo siempre que no utilice la API de Unity. Los CancelationToken es cierto que me faltó hablar de ellos ya que es un factor importante si queremos detener la Task
Un tema muy interesante y que da para mucho, seguramente lo abarque en algún directo que tengo pensado hacer y así me podéis preguntar y lo hacemos más interactivo. Pero a grandes rasgos si lo que estoy buscando es un junior developer me interesa: que sea una persona con mucha inquietud, que se preocupe por investigar, que esté al día del framework que estemos utilizando y que le guste aprender. Si cuenta con eso y con una buena dirección, a la larga acabará creciendo mucho. En cuanto a los aspectos técnicos cuanto más sepas y puedas demostrar mejor, me gusta que haga proyectos propios y game jams, ya que si no tiene experiencia profesional estos proyectos van a hablar de ti. Si en estos proyectos veo que aplicas patrones, clean code, solid... vas a tener muchos puntos porque ya está por encima de la media. Un compañero con el que trabajé tiene un canal de RUclips totalmente orientado a estos temas, igual te interesa su canal: ruclips.net/channel/UC_7nIbRnRqkz4uK-XbcpCPA
Hola, lo he probado y todo funciona muy bien excepto que quieras guardar el valor que devuelve la Task, que te dice que no se puede guardar void. ¿Alguien sabe como sería??
Como comentaba en el vídeo, en Unity no se utiliza concurrencia ya que no puedes acceder a la API del propio Unity. Las corrutinas se ejecutan de forma asíncrona como las funciones async, a grosso modo la única diferencia es que con las funciones async puedes devolver valores.
Excelente video me encanto, solo una cosa que no llego a entender bien, cuando creaste la primera extensión para que permita correr el async Task en el start, como guardo el valor que me retorna esa función? tengo que crear un void async igualmente y almacenar en esa funcion en un "var" el valor que me retorna async Task o como es la forma para almacenar ese valor en el start ? no se si me hice entender ojala y puedas responderme
La función de extensión está pensada para cuando la función asíncrona no devuelve un valor porque no vamos a esperar que termine. Si nos interesa el valor entonces tenemos que hacer un await dentro de una función asíncrona y esto ya capturará los errores. En el caso del Start: private async void Start(){ var await = MiFuncionAsyncQueDevuelveUnValor(); } Al convertir el Start en async void Unity ya controla los errores.
Me encanta tu contenido, hace tiempo me encontraba buscando alguien que explique sobre programación en C#/Unity a un nivel más elevado que lo que suele encontrarse comúnmente. Tengo una pregunta para hacerte, que arquitectura se usa generalmente para videojuegos en Unity o depende mucho del proyecto? Muchas Gracias!
¡Hola! La verdad es que depende de los requisitos del proyecto, pero para mí hay algunos factores comunes, o unos valores mínimos que debe respetar: - La lógica tiene que estar separa de la representación visual. - Si se trabaja con servicios deberíamos de utilizar abstracciones para prevenir posibles cambios. - Nuestra lógica, o la capa del dominio, tiene que ser independiente, no debe de conocer ninguna capa externa. - Nuestro modelo de datos se debe quedar en la capa de datos, la vista no puede tener acceso a estos objetos. Te recomiendo que le eches un vistazo a este vídeo: ruclips.net/video/t5MJiLvKwXQ/видео.html donde hablamos de Clean Architecture y la regla de la dependencia, para mí está regla es sagrada 😊.
Podríamos usar los async o IEnumerator para casos de habilitar funciones en base al tiempo? ejemplo el enfriamiento de una habilidad o el tiempo entre ataques. Que diferencias y especificamente de performance tiene esto en relacion al timer mas conocido ( timer -= Time.deltaTime ). Podriamos realizar un generico con delegados para estos tipos de casos? De esta manera reducir el tiempo que uno coloca al crear cada timer por separado repitiendo la misma lógica con diferente parámetro.
@@charlie12486 Tambirn puedes contrplar variables y tiempos. Por ejemplo, podrias hacer un tween que demore 5 segundps y al terminar la cuenta realizar la acción que tu quieras, en este caso re-activar la habilodad. Tambien ppdria servirte para animar el lockdown utilozando el fill de la imagen, la verdad es una herramienta muy versatil, solo hay que hecharle imaginación
Diferencia de performance no hay mucha aunque si es verdad que tanto async como IEnumerator tienen cierta gestión que hace Unity por nosotros. Lo que comentas estaría perfecto, podrías encapsular esta lógica en una clase, decirle que empiece a contar en una async y que te avise cuando termine. Si no necesitas reflejar este cooldown en la vista simplemente puedes utilizar un Task.Delay y esto va a ser más optimo que restar en cada tick, pero si necesitas mostrarlo en la UI no te queda otra que ir restando. También puedes utilizar tweeners como dice Diego. Yo los utilizo muchísimo para la vista, pero si lo que quiero es tenerlo aislado de la representación visual prefiero utilizar otras alternativas como las funciones async. Una forma muy simple de hacerlo podría ser esta: public async Task WaitAndCall(float secondsToWait, Action callback) { await Task.Delay(TimeSpan.FromSeconds(secondsToWait)); callback(); }
@@ThepowerupsLearning yo para la vista lo que hago es lanzar scriptable events, de esa manera no tienes que usar callbacks, simplemente registrar y desregistrar los scripts de la ui a los eventos que pueden venir de donde quieras, hay un ejemplo de esto en la charla unite de 2017, ruclips.net/video/raQ3iHhE_Kk/видео.html
Genial! Esto me obliga a preguntar sobre una aclaración, y una duda: Aclaración: El método async es de C# y las corrutinas de Unity? Duda: Hasta que punto todos los conceptos de C# se aplican en Unity? PD: soy programador de Java y .NET es totalmente nuevo para mi. Recomiendas algún recurso para estudiar las bases de C#
La verdad es que no existe una diferencia entre C# y Unity ya que para poder utilizar las características de C# Unity las tiene que incorporar en su compilador. Las funciones asíncronas son "nuevas" porque hasta hace poco Unity no las soportaba pero cuando se movieron al .NET 2.0 las incluyeron. Como Unity ahora sigue el estándar de .NET 2.0 y puedes configurarlo para utilizar 4.0, cualquier feature de C# que esté incluida en estas versiones las puedes utilizar sin problema. Creo que más que un curso es intentar estar al día de las actualizaciones del lenguaje, y por ejemplo ver las diferencias entre .NET 2.0 y 4.0.
¡Hola! El curso de SOLID es para gente que ya ha hecho algún videojuego y quiere mejorar. En el curso se asume que conoces Unity y cómo trabajar con él, partimos de un proyecto base y lo vamos refactorizando a medida que aprendemos los distintos principios y Clean Code.
¡Hola Dani! Estoy intentando poner en práctica todo lo que enseñas y estoy empezando a hacer funciones asíncronas en lugar de corrutinas pero me he encontrado un problema: en un proyecto webgl donde el jugador hace login en Playfab (ya te digo que estoy poniendo en práctica todo jajaja), para esperar a la respuesta de Playfab tengo que usar corrutinas porque por lo visto webgl no admite operaciones asíncronas (o por lo menos muchas de ellas). Por ejemplo, un await de 3 segundos no se llega a ejecutar sin embargo, una corrutina sí. ¿Habría alguna forma de no usar corrutinas para esperar la respuesta? Otra solución que se me había ocurrido es llamar a una función cuando tengo un callback con el resultado de Playfab, y así continuar la ejecución desde ahí pero esto me hacía tener dependencias circulares. ¿Cómo lo harías tú? Muchas gracias y un saludo. Siento haberme perdido el directo pero ¡espero estar la próxima vez!
¡Hola MoloSolo! Me hace muy feliz ver que estas aplicando todo lo que explico en el canal :D No he trabajado con Webgl así que no conozco los detalles, pero lo que yo intentaría hacer es un Adapter de la corrutina para poder tratarla como una función asíncrona y así tener un código homogéneo. Esto lo puedes hacer con una clase que escuche el callback y entonces de por terminada la Task y devuelva el resultado. La función de extensión "AsCoroutine" que se ve en el vídeo te puede dar una idea, es parecido pero a la inversa. Otra opción es buscar una librería que ya haga esto, para eso tienes UniTask (github.com/Cysharp/UniTask) que viene de otra librería llamada UniRx (y que en el canal haremos algún vídeo en algún momento). Esta librería tiene su implementación de Coroutines y Task para Unity que son más optimas y permite convertir Corrutinas en UniTask. No te se dar los detalles concretos porque ya hace bastante que no la utilizo pero la documentación que tienen es muy buena y seguro que encuentras ejemplos de lo que necesitas (o parecido). Una opción más que se me ocurre, y que no se si funcionará, es en lugar de hacer un await y esperar hasta que termine, hacer un while, comprobar si ya ha terminado y si no solo esperar 1 frame. Muy parecido al "AsCoroutine". En el vídeo del patrón State, sobre el minuto 11, puedes ver una Task que en lugar de esperar un tiempo concreto, lo que hace es comprobar la condición en cada frame y hacer un Yield hasta el siguiente frame. ¡Ojalá te ayude o al menos te de alguna idea! ¡Un saludo!
@@ThepowerupsLearning Muchas gracias por las respuestas. Me he planteado usar UniTask, he leído que funciona muy bien. Como ahora mismo ya consigo lo que quería con corrutinas, voy a ver si consigo implementar lo mismo con UniTask o con alguna de las otras soluciones ahora que ya no tengo la presión de que funcione jejeje. ¡Muchas gracias!
El video que mejor explica el tema :)
Mil gracias.
Mamma mia esas encapsulaciones en extension methods me han alegrado el día 😍🤤
A seguir así!!!
¡Qué hermosura las funciones de extensión, eh!
Tela marinera... Tengo que verme los vídeos otra vez con una libreta porque son cosas muy importantes y creo que hacemos mal por costumbre.
¡Gracias Dani!
Nos pasa a todos, y me incluyo, cuando llevas años haciendo algo de cierta forma te cuesta mucho cambiarlo por alguien diga "es mejor", y muchas veces ocurre que ni nos enteramos de la actualización y seguimos a la nuestra xD
Gracias por compartir Dani!
Un placer!
acabo de descubrir el canal. muy bueno el vídeo, estaría bien que hicieras mas videos sobre Tasks en Unity.
¡Gracias por el feedback! ¿Qué te gustaría ver de las Tasks?
🔵 Discord: discord.gg/KWABp4BfN4
❤️❤️❤️ CURSO DE SOLID ❤️❤️❤️
👉 thepowerups-learning.com/curso-de-solid/
😱😱😱 Cupón de descuento: POWER30 👈👈👈👈👈👈
🔝🔝🔝🔝🔝 🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝
Uy has mencionado el multi thread de dots (Jobs) muy buen video como siempre.y ganas de ver el de dots
¡Gracias! Yo también tengo ganas de hacer el de DOTS :D
Gran contenido explicado de un modo excelente
¡Gracias! 😁
A buenas horas encuentro esto. Soy diseñador gráfico y hago juegos en mi timepo libre, he aprendido a programar con RUclips y Google. En unas semanas sacaré mi primer juego en Steam y sí, mi código es un caos. Cada vez q quiero cambiar o añadir cosas tengo que modificar varios scripts de 1,000 o 2,000 lineas >.< Justo hace un par de días he aprendido a cambiar todos los callback de Playfab por Task. Ojalá supiese controlar todas estas cosas. Buen vídeo.
Poco a poco, tiene mucho mérito ser diseñador gráfico y hacerce un juego uno solo, para el siguiente ya has aprendido todo eso 😁
Hey muchas gracias por compartir tu conocimiento, me parece excelente video y con mas contenido del esperado (el cual es genial). De cierta forma, considero que hizo falta hablar de los cancellation token ya que los threads no son controlados por el UnitySynchronizationToken sino por el default del lenguaje.
Miento. Despues de seguir investigando, creo que los metodos asincronicos creados por los usuarios corren en el main thread debido al UnitySynchronizationContext. Sin embargo este se puede remplazar para correr en otros threads. Estoy en lo correcto, cierto?
Hola! Sí, van en el hilo peincipal pero se puede hacer que corra en paralelo siempre que no utilice la API de Unity. Los CancelationToken es cierto que me faltó hablar de ellos ya que es un factor importante si queremos detener la Task
@@ThepowerupsLearning gracias :)
Suscrito! Excelente... nivel maestro!! PD-Off Topic: Unity 2020 no mola? ;)
¡Gracias! Unity 2020 mola pero no es LTS, para estos vídeos no tiene más importancia pero para hacer algún proyecto prefiero LTS
Intuí tu respuesta, al 100% ;) la funcionalidad de Unity Hub va perfecta para estos menesteres. Gracias por tu canal, para mi es AAA ;)
Muchas gracias por el vídeo! Muy bien explicado y muchas gracias por los tips de entrevistas de trabajo
Un tema muy interesante y que da para mucho, seguramente lo abarque en algún directo que tengo pensado hacer y así me podéis preguntar y lo hacemos más interactivo.
Pero a grandes rasgos si lo que estoy buscando es un junior developer me interesa: que sea una persona con mucha inquietud, que se preocupe por investigar, que esté al día del framework que estemos utilizando y que le guste aprender. Si cuenta con eso y con una buena dirección, a la larga acabará creciendo mucho.
En cuanto a los aspectos técnicos cuanto más sepas y puedas demostrar mejor, me gusta que haga proyectos propios y game jams, ya que si no tiene experiencia profesional estos proyectos van a hablar de ti. Si en estos proyectos veo que aplicas patrones, clean code, solid... vas a tener muchos puntos porque ya está por encima de la media.
Un compañero con el que trabajé tiene un canal de RUclips totalmente orientado a estos temas, igual te interesa su canal: ruclips.net/channel/UC_7nIbRnRqkz4uK-XbcpCPA
@@ThepowerupsLearning tu conocimiento es oro para mi ;) voy a echarle un ojo, gracias!!
@@javierherasalcuaz ¡De nada!
Hola, lo he probado y todo funciona muy bien excepto que quieras guardar el valor que devuelve la Task, que te dice que no se puede guardar void. ¿Alguien sabe como sería??
Podrías hacer un video sobre concurrencia y paralelismo? No tengo experiencia con corutinas, solo con funciones asíncronas
Como comentaba en el vídeo, en Unity no se utiliza concurrencia ya que no puedes acceder a la API del propio Unity. Las corrutinas se ejecutan de forma asíncrona como las funciones async, a grosso modo la única diferencia es que con las funciones async puedes devolver valores.
Excelente video me encanto, solo una cosa que no llego a entender bien, cuando creaste la primera extensión para que permita correr el async Task en el start, como guardo el valor que me retorna esa función? tengo que crear un void async igualmente y almacenar en esa funcion en un "var" el valor que me retorna async Task o como es la forma para almacenar ese valor en el start ? no se si me hice entender ojala y puedas responderme
La función de extensión está pensada para cuando la función asíncrona no devuelve un valor porque no vamos a esperar que termine. Si nos interesa el valor entonces tenemos que hacer un await dentro de una función asíncrona y esto ya capturará los errores. En el caso del Start:
private async void Start(){
var await = MiFuncionAsyncQueDevuelveUnValor();
}
Al convertir el Start en async void Unity ya controla los errores.
Me encanta tu contenido, hace tiempo me encontraba buscando alguien que explique sobre programación en C#/Unity a un nivel más elevado que lo que suele encontrarse comúnmente.
Tengo una pregunta para hacerte, que arquitectura se usa generalmente para videojuegos en Unity o depende mucho del proyecto? Muchas Gracias!
¡Hola! La verdad es que depende de los requisitos del proyecto, pero para mí hay algunos factores comunes, o unos valores mínimos que debe respetar:
- La lógica tiene que estar separa de la representación visual.
- Si se trabaja con servicios deberíamos de utilizar abstracciones para prevenir posibles cambios.
- Nuestra lógica, o la capa del dominio, tiene que ser independiente, no debe de conocer ninguna capa externa.
- Nuestro modelo de datos se debe quedar en la capa de datos, la vista no puede tener acceso a estos objetos.
Te recomiendo que le eches un vistazo a este vídeo: ruclips.net/video/t5MJiLvKwXQ/видео.html donde hablamos de Clean Architecture y la regla de la dependencia, para mí está regla es sagrada 😊.
Podríamos usar los async o IEnumerator para casos de habilitar funciones en base al tiempo? ejemplo el enfriamiento de una habilidad o el tiempo entre ataques. Que diferencias y especificamente de performance tiene esto en relacion al timer mas conocido ( timer -= Time.deltaTime ). Podriamos realizar un generico con delegados para estos tipos de casos? De esta manera reducir el tiempo que uno coloca al crear cada timer por separado repitiendo la misma lógica con diferente parámetro.
Podrías usar tweeners, son extremadamente útiles y faciles de entender.
@@diegodetomas4240 Pero los tweeners no son específicos para animación? como lo usarías para estos casos?
@@charlie12486 Tambirn puedes contrplar variables y tiempos. Por ejemplo, podrias hacer un tween que demore 5 segundps y al terminar la cuenta realizar la acción que tu quieras, en este caso re-activar la habilodad. Tambien ppdria servirte para animar el lockdown utilozando el fill de la imagen, la verdad es una herramienta muy versatil, solo hay que hecharle imaginación
Diferencia de performance no hay mucha aunque si es verdad que tanto async como IEnumerator tienen cierta gestión que hace Unity por nosotros.
Lo que comentas estaría perfecto, podrías encapsular esta lógica en una clase, decirle que empiece a contar en una async y que te avise cuando termine. Si no necesitas reflejar este cooldown en la vista simplemente puedes utilizar un Task.Delay y esto va a ser más optimo que restar en cada tick, pero si necesitas mostrarlo en la UI no te queda otra que ir restando.
También puedes utilizar tweeners como dice Diego. Yo los utilizo muchísimo para la vista, pero si lo que quiero es tenerlo aislado de la representación visual prefiero utilizar otras alternativas como las funciones async.
Una forma muy simple de hacerlo podría ser esta:
public async Task WaitAndCall(float secondsToWait, Action callback)
{
await Task.Delay(TimeSpan.FromSeconds(secondsToWait));
callback();
}
@@ThepowerupsLearning yo para la vista lo que hago es lanzar scriptable events, de esa manera no tienes que usar callbacks, simplemente registrar y desregistrar los scripts de la ui a los eventos que pueden venir de donde quieras, hay un ejemplo de esto en la charla unite de 2017, ruclips.net/video/raQ3iHhE_Kk/видео.html
Genial!
Esto me obliga a preguntar sobre una aclaración, y una duda:
Aclaración: El método async es de C# y las corrutinas de Unity?
Duda: Hasta que punto todos los conceptos de C# se aplican en Unity?
PD: soy programador de Java y .NET es totalmente nuevo para mi.
Recomiendas algún recurso para estudiar las bases de C#
La verdad es que no existe una diferencia entre C# y Unity ya que para poder utilizar las características de C# Unity las tiene que incorporar en su compilador. Las funciones asíncronas son "nuevas" porque hasta hace poco Unity no las soportaba pero cuando se movieron al .NET 2.0 las incluyeron.
Como Unity ahora sigue el estándar de .NET 2.0 y puedes configurarlo para utilizar 4.0, cualquier feature de C# que esté incluida en estas versiones las puedes utilizar sin problema.
Creo que más que un curso es intentar estar al día de las actualizaciones del lenguaje, y por ejemplo ver las diferencias entre .NET 2.0 y 4.0.
el curso de solid para que nivel de programador estaria destinado?
gracias
¡Hola! El curso de SOLID es para gente que ya ha hecho algún videojuego y quiere mejorar. En el curso se asume que conoces Unity y cómo trabajar con él, partimos de un proyecto base y lo vamos refactorizando a medida que aprendemos los distintos principios y Clean Code.
¡Hola Dani!
Estoy intentando poner en práctica todo lo que enseñas y estoy empezando a hacer funciones asíncronas en lugar de corrutinas pero me he encontrado un problema: en un proyecto webgl donde el jugador hace login en Playfab (ya te digo que estoy poniendo en práctica todo jajaja), para esperar a la respuesta de Playfab tengo que usar corrutinas porque por lo visto webgl no admite operaciones asíncronas (o por lo menos muchas de ellas). Por ejemplo, un await de 3 segundos no se llega a ejecutar sin embargo, una corrutina sí.
¿Habría alguna forma de no usar corrutinas para esperar la respuesta?
Otra solución que se me había ocurrido es llamar a una función cuando tengo un callback con el resultado de Playfab, y así continuar la ejecución desde ahí pero esto me hacía tener dependencias circulares.
¿Cómo lo harías tú?
Muchas gracias y un saludo. Siento haberme perdido el directo pero ¡espero estar la próxima vez!
¡Hola MoloSolo!
Me hace muy feliz ver que estas aplicando todo lo que explico en el canal :D
No he trabajado con Webgl así que no conozco los detalles, pero lo que yo intentaría hacer es un Adapter de la corrutina para poder tratarla como una función asíncrona y así tener un código homogéneo. Esto lo puedes hacer con una clase que escuche el callback y entonces de por terminada la Task y devuelva el resultado. La función de extensión "AsCoroutine" que se ve en el vídeo te puede dar una idea, es parecido pero a la inversa.
Otra opción es buscar una librería que ya haga esto, para eso tienes UniTask (github.com/Cysharp/UniTask) que viene de otra librería llamada UniRx (y que en el canal haremos algún vídeo en algún momento). Esta librería tiene su implementación de Coroutines y Task para Unity que son más optimas y permite convertir Corrutinas en UniTask. No te se dar los detalles concretos porque ya hace bastante que no la utilizo pero la documentación que tienen es muy buena y seguro que encuentras ejemplos de lo que necesitas (o parecido).
Una opción más que se me ocurre, y que no se si funcionará, es en lugar de hacer un await y esperar hasta que termine, hacer un while, comprobar si ya ha terminado y si no solo esperar 1 frame. Muy parecido al "AsCoroutine". En el vídeo del patrón State, sobre el minuto 11, puedes ver una Task que en lugar de esperar un tiempo concreto, lo que hace es comprobar la condición en cada frame y hacer un Yield hasta el siguiente frame.
¡Ojalá te ayude o al menos te de alguna idea! ¡Un saludo!
@@ThepowerupsLearning Muchas gracias por las respuestas. Me he planteado usar UniTask, he leído que funciona muy bien. Como ahora mismo ya consigo lo que quería con corrutinas, voy a ver si consigo implementar lo mismo con UniTask o con alguna de las otras soluciones ahora que ya no tengo la presión de que funcione jejeje.
¡Muchas gracias!