Saltar navegación

Tutoría 5 - DEIM - UT2 y 3 - Curso 23·24 - 25 Enero - 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 enero de 2024 por Daniel M.

45 visualizaciones

Grabación de la tutoría 5 de DEIM.

Descargar la transcripción

Vale, en la tutoría de hoy estaba hablando ahora con uno de vosotros, con un compañero 00:00:00
que ha asistido, sobre la tarea 2 y bueno, que a veces es un poco frustrante no dar al 00:00:09
mejor con el enfoque con el que se van resolviendo lo que se pide las prácticas, ¿no? 00:00:15
Pero es normal que tarde un poco en llegar a la solución, ¿me explico? 00:00:22
a medida que se va teniendo más soltura y se va conociendo mejor el lenguaje de programación 00:00:27
por ejemplo en este caso, pues es más fácil caer en una forma de resolver algo que nunca 00:00:32
habías tenido antes que enfrentarte, pero lo importante es que el código que vayamos 00:00:40
viendo o que vayáis escribiendo entendáis qué es. 00:00:44
Antes lo ha dicho este compañero, que es verdad que está la frase de que la mitad 00:00:47
del tiempo de trabajo de un programador es estar mirando en Google para dar con las 00:00:52
soluciones o porque es un nuevo enfoque, que si a veces os perdéis un poco en el enfoque, 00:00:56
que es normal, hay que dar con ello. 00:01:05
También le comentaba, bueno, para resolver dudas una vez ya estéis estancados y no sepáis 00:01:08
salir, recordad que tenéis el foro para escribirme y en un tutorial como este, ahora por ejemplo 00:01:13
voy a resolver alguna duda que hay en el foro sobre la tarea 2 y plantando dudas sobre 00:01:19
todo cuando os atajeéis de una forma imposible de avanzar. 00:01:28
Y luego hay otra fórmula que no sé si alguno ya ha investigado que es las herramientas 00:01:31
de inteligencia artificial, y esto no es para que os haga las prácticas, además no es 00:01:37
posible que os haga una práctica de las que estamos planteando, pero a veces cuando tengáis 00:01:41
dudas en un código podéis copiar ese código, por ejemplo en ChatGPT, y decirle oye explícame 00:01:45
línea a línea qué es este código y a lo mejor os da unas indicaciones, unas pistas 00:01:52
o os sugiere otros enfoques y esto sólo sirve si vais entendiendo las bases de programación 00:01:57
y de código. 00:02:03
Una vez eso, pues estas herramientas precisamente se están creando para ayudarnos, entonces 00:02:04
también podéis explorarlas, no está prohibido que uséis ChatGPT, ChatGPT tiene la pega 00:02:09
de que os puede escribir un script pero luego lo tenéis que implementar, ubicarlo bien, 00:02:14
pasar las variables, es decir, hasta que no se entiende cómo funciona o qué hace cada 00:02:20
componente dentro del editor de Unity, es una ayuda, pero no es sustitutivo, al menor 00:02:24
de momento. 00:02:30
Por tanto, os digo esto también por si en algún momento os bloqueáis, que sé que 00:02:31
es muy frustrante y es normal, que yo cuando doy las clases sé por dónde tirar porque 00:02:36
ya lo he resuelto, ya me he enfrentado y ya lo he solucionado y aparte también a veces 00:02:42
tengo hasta una chuleta aquí por si alguna cosa que sé que no me va a salir, es decir, 00:02:47
que es normal, que cueste y a veces es darle vueltas y cambiar y modificar, ¿vale? 00:02:53
Simplemente que me parece importante en este momento del curso que ya empezamos a meternos 00:02:58
en cosas más complejas y que implica usar muchos ingredientes, pues creo que es importante 00:03:02
comentar esto. 00:03:09
No sé si tenéis alguna duda de primeras que queráis resolver, si no paso con las 00:03:10
que hay en el foro o lo que han escrito. 00:03:21
Voy a compartir pantalla también. 00:03:24
Vale, pues me dicen que hay dudas sobre la tarea de la unidad 3. 00:03:27
Si te parece, eso, explico alguna cosilla que creo relevante del tema 2 y de las dudas 00:03:40
que había y pasamos a eso, ¿te parece? 00:03:49
Venga, pues a ver, tengo aquí preparado en el foro de la unidad 2, lo pongo aquí, entiendo, 00:03:53
se ve la pantalla, ¿verdad? 00:04:00
Se está viendo, confirmadme, no vaya a ser que me ponga a hablar y que ya ha pasado veces. 00:04:01
Vale, perfecto, muchas gracias, se ve. 00:04:07
Todo bien, vale. 00:04:13
Una compañera, bueno, puso una frase que como ya os he dicho, que a veces es habitual, ¿vale? 00:04:14
Hay que tranquilizarse y bueno, aquí hizo bien en preguntar y buscar en internet. 00:04:19
Vale, ponía que ya había conseguido que la nave fuera hacia adelante. 00:04:26
Dejé la respuesta por aquí, voy a comentar un poco lo que le puse, pero por favor, sé 00:04:34
que son los enunciados de las tareas muy largos y en alguna tarea, creo que de hecho en esta, 00:04:37
ponía leed primero todo el enunciado con atención y luego ya empezáis otra vez de 00:04:42
arriba a abajo para tener primero toda la imagen de la tarea y luego ya se va desglosando. 00:04:46
Porque ponía que la nave salía disparada hacia adelante y había conseguido moverla 00:04:51
en profundidad y era algo que precisamente indicaba que no había que hacer, es decir, 00:04:55
lo que se iban a mover hacia la cámara son los obstáculos, ¿vale? 00:04:59
Entonces, aquí había generado varias variables, también hay un problema a veces que es normal, 00:05:02
me consultéis a través del foro, que es que necesito contexto, porque a lo mejor 00:05:11
un código es algo muy evidente lo que está fallando o lo que me preguntáis, pero en 00:05:16
otros no sé por qué estáis empleando ciertas cosas y es verdad que es complejo, si no estoy 00:05:20
ahí con vosotros en el ordenador, que me lo transmitáis, ¿vale? 00:05:25
Por ejemplo, la otra duda, había alguna captura de imagen un poco más concreta, ¿vale? 00:05:28
Pero bueno, cosas que hay que tener en cuenta, que vi aquí, que dijo la compañera, es que 00:05:33
una parte vi que dentro del update hacía operaciones que entiendo que no eran muy 00:05:40
conscientes de qué buscaban, porque por ejemplo, aquí ve un condicional que es si al pulsar la 00:05:46
tecla W y luego pone bastantes condiciones o cosas que quiere que se ejecute con esa 00:05:52
condición, porque si no la condición aquí ahora mismo no está haciendo nada, recordad que hay que 00:06:00
poner las llaves, lo ponía aquí un poco más abajo, si ponemos esta orden estamos poniendo que al 00:06:04
pulsar W solo va a ejecutar la primera línea, ¿vale? Veréis en los apuntes a veces, por ejemplo, 00:06:09
en el apartado que hay sobre las interacciones, que pone ejemplos, que pone si pulsas el botón 00:06:16
izquierdo del ratón ocurre esto, si es solo una instrucción no hace falta abrir llaves, ¿vale? 00:06:23
Y se ejecuta la siguiente línea o instrucción hasta el punto y coma. Si vamos a poner más, 00:06:28
aquí solo hay una, aquí habría que ver, esto sería la versión, si es lo que quería hacer la compañera, 00:06:33
al pulsar W se ejecuta todo esto si se cumple la condición. Y luego hay otra cosa que es que 00:06:39
esta orden lo único que estaba haciendo era generar nuevas variables de tipo vector3 con 00:06:45
estos nombres que tenemos aquí, ¿vale? Estos y les está dando una dirección matricial, es decir, 00:06:50
en este caso un 1 0 0, aquí un 0 0 menos 1, ¿vale? Pero no estaba haciendo nada. Bueno, sí, estaba 00:06:57
generando unas variables y había guardado un valor, pero no estaba haciendo que se moviera, 00:07:05
que es lo que entiendo que pretendía. Recordad que para que se mueva lo que hay que cambiar no 00:07:09
es generando un vector, es el transform, ¿vale? Habrá que darle un valor de movimiento, que es, 00:07:14
por ejemplo, en la duda de la persona, pues aquí, por ejemplo, transform position, aquí estás 00:07:23
cambiando la posición a la que ponga newPos, ¿vale? Aquí sí estamos afectando la posición. Si ponemos 00:07:30
algo que es un tipo de variable y su nombre, estamos generando una variable, ¿vale? Esto ya 00:07:36
lo hemos visto en otros momentos y entonces ya lo hemos visto. Si hay dudas, me paráis o me 00:07:41
volvéis a escribir en base a esto. Luego veo también, y una cosa importante es que cuando 00:07:50
tenemos la nave y este script de PlayerController en el contexto de la práctica de la nave, 00:07:58
el script debería estar aplicado a la propia nave, en principio. Se puede hacer de más formas, ¿no? 00:08:03
Entonces, lo que sí que he visto es que por Serialize se ha puesto un transform a otro objeto, 00:08:07
¿vale? Y cuando en la práctica uno instanciábamos y arrastrábamos, creábamos un empty, ¿vale? Y en 00:08:13
ese poníamos el código y luego por código referenciábamos a un prefab, ahí sí estamos 00:08:27
hablando de otro objeto que se tiene que instanciar. Pero si es la misma nave la que 00:08:31
tiene el script, me parece raro, no digo por si acaso es ese el concepto, poner otro objeto. No, 00:08:35
tú lo que vas a querer mover es la posición del objeto que lo tiene, ¿vale? Como, por ejemplo, 00:08:41
pasará luego con los obstáculos. Ahora lo vemos, pero los obstáculos lo que hay que hacer es ponerle 00:08:46
a cada obstáculo en su prefab, es la solución más obvia, un script que lo que haga es que se 00:08:51
mueva continuamente hacia la pantalla, ¿vale? Por eso lo del otro objeto servirá cuando conectéis 00:08:57
scripts. Si no habéis llegado a esto, ya en algún tema ya se habla de cómo conectar un script con 00:09:05
otro. Iremos capturando coordenadas y posiciones de otros objetos, pero si el propio objeto es el 00:09:10
que tiene el código, ese será el que el que defina el movimiento. Habrá que aludir al OtherObjectPosition, 00:09:17
que a lo mejor hemos pasado el transform del mismo objeto que tiene el script, pero en el caso de 00:09:26
querer moverse a sí mismo hay que hablar del TransformPosition, como ha hecho aquí. Aquí, 00:09:33
lo que pongamos después, lo que va a hacer es mover a la nave, ¿vale? Y luego esto es mediante 00:09:38
una asignación de algo, recordad que para trasladarse y rotar, aquí ahora mismo no ve el 00:09:46
translate, por tanto no sé cómo se mueve, se está moviendo por el position, no está usando el 00:09:52
translate. Transform.Translate es un método que permite hacer que se mueva, pero aludiendo al 00:09:56
transform del objeto que tiene el script. Hasta aquí no sé si hay dudas, pero me parece importante 00:10:02
esto que si alguna vez veis un if sin llaves, lo que se va a ejecutar en la primera instrucción, 00:10:07
es como una forma simplificada, ¿vale? Y aquí este punto y coma en la condición sobra también, 00:10:13
¿vale? Aquí yo lo dejé, esto no es correcto. Después del condicional ya iría la llave o la 00:10:19
instrucción directamente, nunca hay un punto y coma, al menos no de forma estándar. Vale, 00:10:25
de aquí hay varias cosas que habría que ver el enfoque, ¿vale? Pero bueno. Luego, 00:10:33
otra cosa importante es que, no sé, otra compañera me habló de que al hacer el input que no 00:10:38
encontraba el GetKeyLeft o el GetKeyRight, no, el GetKeyDown o Up se refiere a si pulsamos o 00:10:46
soltamos, esto lo pone en los apuntes y lo vimos también en otra tutoría, si no, por favor revisadla, 00:10:53
se refiere al momento de bajar la tecla o el botón, subir la tecla, soltar el botón, ¿vale? Lo de 00:10:57
Left y Right significa que alguien está entendiendo que esto lo que hace es que la nave se mueva hacia 00:11:04
arriba o hacia abajo. No, esto significa al pulsar esta tecla y aquí tenemos que poner un Translate, 00:11:09
pues si es hacia la derecha igual es un Right o un Forward, ¿vale? Pero no existe el GetKeyLeft 00:11:14
directamente, va a decir, ah, si pulsas ahí va a la izquierda. No, ese método no existe, ¿vale? 00:11:20
Luego había otra duda en el foro de otra compañera, ya os digo, di una respuesta ya, 00:11:27
si la veis, pero bueno, quiero comentar alguna cosa. Cuando voy a enseñar un momento en el 00:11:34
editor, por ejemplo, mi planteamiento de esta tarea, a ver, creo que no he cambiado nada, 00:11:41
muy susceptible de cambiar, ¿vale? Pues yo cuando le doy a Play, ¿vale? Veis que lo que va apareciendo 00:11:50
son clones de este Prefab que yo tengo aquí, que es el Obstacle, se llama así porque lo llama así, 00:11:56
¿vale? Se van generando y de vez en cuando desaparece, aparece otro y cada vez que hacemos 00:12:01
un clon por instanciación pone un apellido al nombre de ese objeto que pone Clone, ¿vale? Lo 00:12:06
digo porque en la incaptura de imagen, ¿vale? Por si alguna vez os volvéis a encontrar con algo así, 00:12:12
¿vale? Me dice, se me están copiando cientos de clones, de pronto, en vez de ir saliendo cuando 00:12:20
quiero, salen. Fijaos que se está añadiendo la etiqueta de Clone muchas veces y eso significa 00:12:28
que están creándose clones de ese Clone, es decir, se ha creado este Clone y luego a partir de éste 00:12:32
se está haciendo más copia de ese Clone. ¿Por qué pasa esto? Si analizamos el código, está 00:12:39
bastante bien enfocado, le falta algún detallito, pero bueno, que estos son los pasitos normales. 00:12:46
Igual que hicimos en la primera práctica, estamos instanciando un Prefab, que es ese obstáculo, 00:12:51
este pivote, ¿vale? Luego aludía también al obstáculo en sí dentro de este script, ¿vale? 00:12:57
Así mismo, en realidad. ¿Por qué? Bueno, guardaba ese obstáculo, lo usaba para guardar la instancia 00:13:06
dentro de una variable, ¿vale? Porque lo que hacía era crear estos obstáculos mediante 00:13:13
una corrutina, ¿vale? Que decía, cuando llegue a tres copias, porque cada vez que se hace una copia 00:13:21
se está guardando una instancia más, se está calculando más instancias, cuando cree tres copias deja 00:13:26
de instanciar, ¿vale? Y esto tiene lógica cuando lo decimos en plan, yo no quiero que haya 00:13:33
infinitos obstáculos, quiero en este caso que haya tres. Pero tened en cuenta que si creamos tres y se 00:13:38
están moviendo, pues desaparecerán y ya no habrá más, ¿vale? O hay que seguir generando instancias, 00:13:43
porque a medida que se van moviendo, si hay tres, luego en este código no hay ningún momento en el 00:13:50
que reduzcamos este número, ¿vale? Entonces, echarle un ojo. Y algo importante, si ya vais 00:13:54
usando para esta práctica, se podía hacer a lo mejor de otra forma, pero la lógica con lo que 00:14:01
hemos visto es esta. Cuando empieza el juego, se empieza en el Start activando dos corrutinas, en 00:14:06
este caso. Y este es uno de los problemas que hay, meter las dos corrutinas en un mismo script, ¿vale? 00:14:12
Me explico. Al final, voy a, por ejemplo, a como lo tengo resuelto yo, que en realidad es algo muy 00:14:17
parecido. Yo tengo este pivot estáculo, un nulo ya colocado en profundidad en Z, ¿vale? Porque luego lo 00:14:24
que voy a variar, lo que ponen las instrucciones, es que pondremos un número aleatorio en el eje 00:14:30
horizontal, para que siempre creándose en este 200, pues uno esté en el menos 20, otro en el 20, 00:14:35
o en el 30, ¿vale? Se vaya aleatorizando, ¿vale? Entonces, importante, cuando activamos una corrutina, 00:14:44
las corrutinas, por defecto, hay que tener cuidado de ponerlas en el Start, o ponerlas en un 00:14:53
momento que sólo se active una vez. ¿Por qué? Porque si esta corrutina la empezamos en el Update, 00:15:02
es decir, cada fotograma, cada fotograma empezará a ejecutarse, ¿vale? No es lo que ha pasado aquí, 00:15:07
pero ojo, eso es importante. Que si ponemos en el Update que se genera una corrutina, que sea 00:15:12
porque hay una condición que se lanza a veces, o una vez sólo. Porque si no, estaríamos cada 00:15:17
fotograma en el Update, llamando a esta corrutina que haría estas instrucciones en paralelo. Las 00:15:22
corrutinas se llaman así porque a la rutina, a lo que está ocurriendo, digamos, mientras estamos 00:15:28
ejecutando el juego, en paralelo se abre otro proceso que podemos ponerle otro código, ¿vale? 00:15:35
Otras instrucciones, con este enumerator, que es una orden de interfaz, ¿vale? Bueno, eso da un poco 00:15:40
igual. Tened cuidado de controlar cuántas veces lancéis las corrutinas. Además, si fuéramos lanzando 00:15:45
la corrutina muchas veces, al abrirse tantos procesos en paralelo y no cerrarlo nunca, si no 00:15:53
ponemos un StopCorroutine, como pasaría aquí, el juego en algún momento empezará a ir lento, a 00:15:59
crasear, etcétera, ¿vale? Porque cada vez iremos llevando más recursos. Entonces, aquí lo que ha 00:16:03
pasado es que este script, yo entiendo, este script que crea obstáculos, ¿vale? A lo mejor sí que creaba 00:16:10
solo tres, pero si estaba puesto en cada obstáculo, es decir, dentro del prefab, ¿vale? Porque recordad 00:16:18
que un propio prefab, igual que yo he puesto aquí, que el prefab en sí siempre se mueva, que es lo 00:16:25
que hace este script, hacia la pantalla, ¿vale? Si le ponemos que cada vez que instanciamos un objeto, 00:16:30
tenga dentro, en este caso un obstáculo, tenga dentro un script que también dice, oye, cada copia, 00:16:37
cada copia al lanzarse, y es un poco lo mismo que os decía de tener cuidado al lanzar corrutinas, 00:16:45
a ver que no... que estábamos aquí, ¿vale? Si esto lo ponemos a cada uno de los obstáculos, cuando se 00:16:48
lanza el obstáculo, cada obstáculo va a tener hasta tres instancias, porque las estamos aquí lanzando. 00:16:55
Entonces, ¿cuál es la solución? En vez de que haya infinitos scripts lanzando copias, 00:16:59
solo habrá que ponerlo en uno, ¿vale? Igual que hacíamos en la práctica 1. He puesto aquí un 00:17:07
AntiObject, que este, abro el código, bueno, un AntiObject, y abro el código que tengo yo, 00:17:13
por ejemplo, ¿vale? Que lo que hace, y se parece mucho a lo que ha hecho la compañera, ¿vale? Con 00:17:23
un intervalo de tiempo, que bueno, aquí está generado para que relacione la velocidad con la 00:17:28
distancia a la rapidez, pero podéis poner un número rápidamente, ¿vale? Pues se lanza una corrutina en 00:17:34
el Start, igual que ha hecho la compañera, y en todo momento haya un bucle que cada cierto tiempo 00:17:39
que marcamos con este intervalo, o podemos poner un 2 si queremos que sea siempre dos segundos, 00:17:45
¿vale? Pues se vaya lanzando una instancia desde ese punto que habíamos puesto, que fijaos que yo, 00:17:49
el instanciador, ese objeto que lanzará este obstáculo, que sí que hemos pasado, igual que 00:18:00
la tarea 1, por un SerializeField, ¿vale? Siempre le estamos diciendo, ¿vale? La instanciación que se 00:18:05
haga desde el punto Impose, que yo he creado anteriormente, que tendrá ya las posiciones de 00:18:12
Z e Y, que yo ya he marcado en esta posición, las marco yo con el gizmo, vamos, con las coordenadas 00:18:19
del instanciador, ¿vale? Y luego, aparte la X, que sea un número aleatorio, en este caso entre 00:18:27
menos 40 y 40, ¿vale? Y entonces lanzará ese obstáculo en estas coordenadas y hará una vuelta, ¿vale? 00:18:33
Porque el While True es un bucle infinito, ¿vale? Si este bucle infinito no lo pusiéramos en una corrutina, 00:18:40
una corrutina que dijéramos un intervalo de tiempo, en un solo fotograma inmediatamente entraría en 00:18:45
conflicto, porque sería un bucle, que esto se hablaba en el tema cero, que no se cierra, que no está 00:18:51
controlado, entonces se sobrecarga y se va lejos. Por eso, en las corrutinas es súper frecuente poner 00:18:56
bucles que diga, vale, ejecuto aquí, bajo, bajo, bajo, se va ejecutando, hago la instancia y cuando 00:19:02
llego aquí, paro hasta que pase dos segundos, o lo que pongamos aquí. ¿Han pasado segundos? 00:19:07
Vuelvo al bucle y otra vez. Si yo no pusiera esta orden y consiguiera decir, si me metiera un bucle sin 00:19:13
una pausa en medio, ¿vale? Esto se ejecutaría constantemente. Hay otra orden que es, en vez de 00:19:19
poner, por ejemplo, el waitForSeconds, que le decimos un tiempo, si le decimos yieldReturn 00:19:27
null, a una orden dentro de una corrutina, en este momento lo que hace es parar aquí la ejecución y 00:19:34
esperar al siguiente fotograma. Es un poco como hacerlo del update, va por fotogramas. Esto es 00:19:39
importante. Entonces, lo que se ha hecho aquí es este instanciador, igual que la compañera tenía 00:19:45
en un solo script las dos corrutinas, una de crear obstáculo y otra de moverlo en el mismo, 00:19:53
claro, si ponemos también el mover, si mezcláramos también, hiciéramos la operación inversa en este 00:20:00
script que os estaba enseñando, aquí está, también me va a poner la corrutina mover. Claro, 00:20:06
tened en cuenta que es el instanciador el que se movería. Si el instanciador es el que da las 00:20:14
coordenadas de X e Y, se iría moviendo hacia la cámara. Si le pusiéramos que se fuera moviendo 00:20:18
en Z hacia la cámara y se irían haciendo copias, en ese punto, por tanto, saldría de cámara, 00:20:22
se iría haciendo copias y ya no lo veríamos. No sé si me explico. Entonces, recordad que se 00:20:28
pueden aplicar, incluso a un mismo GameObject, se pueden aplicar diferentes scripts y se van 00:20:34
sumando las cosas que hacen. Entonces, la operación más lógica sería que en el propio prefab, 00:20:38
en este obstáculo, vais a ver que ya dentro del prefab hay un script que cada copia, 00:20:45
cada instancia del script, va a tener ya este movimiento por efecto. No cada script va a 00:20:54
instanciar copias porque entonces pasa el problema que he comentado antes. Pero si yo me meto aquí en 00:21:00
el código, os voy a enseñar este, por ejemplo, este es el que hace una variable de velocidad y 00:21:05
en el Update es donde decimos, vale, esto es un back a esta velocidad y recordad que el Update, 00:21:12
además, cuando haya movimientos o rotaciones dentro del Update, que ahora veremos algo más 00:21:18
sobre esto en el tema 3, lo suyo es multiplicarlo por el TimeDeltaTime. Solo una vez, no muchas 00:21:24
veces vamos a usar este movimiento y como que lo vamos variando. Ya os comenté que básicamente lo 00:21:31
que hace esto es devolver el tiempo que hay entre fotograma y fotograma, que varía según la potencia 00:21:36
del ordenador. Sirve para equilibrar que en todos los dispositivos se vea igual, se mueva igual el 00:21:42
objeto. Si tenemos una máquina que procesa mucho, si no ponemos algo de este tipo, pues se 00:21:47
movería más rápido la nave porque cada fotograma para él se ejecuta con menor lapso de tiempo. La 00:21:53
contraindicación que tiene este TimeDeltaTime es que devuelve números tipo 0,2, 0,3, yo que sé, 00:22:00
son números muy pequeños. Entonces, cuando lo multiplicamos, si hemos estado probando esto sin 00:22:08
poner esto y luego lo ponemos, se va a multiplicar y se va a desacelerar mucho. Es normal porque está 00:22:13
aplicando un valor pequeño para equilibrar, pero pequeño. Entonces, siempre esta variable que 00:22:20
ponemos, a lo mejor hay que incrementarla, no hay problema. Si esto me lo ha dividido entre 100, 00:22:26
si esto estuviera sin aplicarlo está a 30, pues igual hay que ponerlo a 3000. No pasa nada, esto 00:22:32
lo controlamos nosotros. Y luego, importante, si yo no... y de hecho lo voy a hacer la prueba. Si yo 00:22:38
comento esto, aquí estoy consiguiendo que el Translate se mueva hacia el Back, es decir, 00:22:46
hacia el Z negativo, hacia la cámara, en este caso, si está bien orientado todo, a una cierta velocidad, 00:22:50
cada objeto que se está instanciando en el punto de instanciador. Voy a guardar y ahora mismo tengo 00:22:56
el juego. Me vuelvo, salgo y juego. Se empieza a ejecutar el juego, se van haciendo las copias 00:23:04
cada dos segundos poner, por eso es regular, y el intervalo también se podría poner un random range, 00:23:13
un número aleatorio, para que no siempre se instancien con el mismo periodo de tiempo. Pero 00:23:18
veis que van pasando los clones y aquí, si dejo este juego ejecutándose mucho tiempo, se irán 00:23:23
acumulando, acumulando, acumulando, y si me muevo en el editor, básicamente, porque esto es un 00:23:28
ejército de obstáculos hasta el infinito. ¿Qué pasa? Que si se van acumulando todos estos clones, 00:23:32
estos clones, llegan a un punto que habrá tanto objeto aquí que va a colapsar o va a ralentizarse. 00:23:37
Por tanto, como a nosotros sólo nos interesa el tiempo en el que los obstáculos están viéndose 00:23:44
en el juego, porque en este juego no vamos a girar y vamos a ver lo que hay detrás, todo lo que pase 00:23:51
de detrás de la cámara, que sería un poco a partir de aquí, todo esto que está ocurriendo aquí, 00:23:56
ya nos da igual que ocurra. De hecho, preferimos que no ocurra para que no se sigan aquí sumando 00:24:01
clones. Para eso está la orden de el destroy. ¿Cuál ha sido el plantamiento? Lo vuelvo a activar. 00:24:05
Ahí está, lo dejo de comentar. Si, como el script lo lleva al propio obstáculo, el transformer alude 00:24:16
a las coordenadas del obstáculo. Decimos, si la Z es menor a menos 10, es decir, si la Z, 00:24:22
por ejemplo, pongo la nave y la voy moviendo para atrás, es menor de menos 10, es decir, cuando pase 00:24:30
detrás de la nave y de la cámara, cuando pase detrás de este punto, lo que voy a hacer es destruir 00:24:34
el GameObject. Si ponemos aquí GameObject, se destruye a sí mismo, es decir, destruye al objeto 00:24:39
que tiene el código. El destroy, si veis la documentación, puede destruir otros objetos, 00:24:45
si los referenciamos de cierta forma. Pero si queremos destruir al propio objeto que tiene 00:24:50
el código, esta sería la orden. Una vez alcancen, como se está moviendo y está el Update refrescando, 00:24:54
cuando el Translate haga que se sobrepase esta coordenada, pues destruyelo, que ya no lo quiero 00:25:01
el objeto. Y vais a ver, a ver si he guardado, que se empiezan generando igual, pero cuando los 00:25:06
pivotetes superan en cierta posición que habíamos marcado, se destruyen y por eso dejan de verse. 00:25:17
¿Qué tal hasta aquí? Ahora lo veremos también, pero a veces la clave de las soluciones es segmentar 00:25:25
los códigos, es decir, hacerlos menos pequeños. Por ejemplo, aquí la compañera está muy bien 00:25:34
enfocado. Es obvio lo que quería hacer con esto de limitar el número de instancias, pero el problema 00:25:40
está en limitar a tres instancias, pero ¿en qué momento puedo hacer más de tres? Porque si no, 00:25:46
a los tres pivotes ya no se puede seguir. Por cierto, la compañera puso aquí una orden, 00:25:51
FOR y estos puntos y comas, que es lo mismo que poner el While True. Significa que se hace un 00:25:57
bucle infinito y, como veréis, lo ha hecho muy bien porque luego, para parar la corrutina cada 00:26:03
cierto tiempo, ha puesto esta orden de NULL que es que, oye, espérate un fotograma para ir moviendo 00:26:10
el obstáculo. Pues tiene sentido porque el Translate, al final, nosotros lo vamos viendo 00:26:15
en cada fotograma, entonces está bien ejecutado. Se podría poner también directamente, 00:26:21
con el While True, por ejemplo, o con un intervalo. En realidad, en mover obstáculos no es necesaria 00:26:29
una corrutina porque se puede hacer, como he puesto, con un Translate en el propio objeto que lleva 00:26:38
el script. Entonces no hace falta usar una corrutina que devuelve en cada fotograma porque ya podemos 00:26:44
usar el Update. Como hemos hecho aquí para moverlo, pues en el propio Update es un poco lo mismo que 00:26:50
abrir la corrutina en este caso. Y ojo que aquí, por ejemplo, faltaría probablemente el TimeDeltaTime. 00:26:57
En cuanto a esto, no sé si hay alguna duda, si se entiende un poco lo que he visto. Si me podéis 00:27:06
decir que os estoy viendo en el chat o si me podéis contestar. ¿Hasta aquí qué tal? Entiendo que con 00:27:15
esto, más o menos, ya las dudas de la tarea están resueltas. Más o menos, claro. Vale, perfecto. 00:27:21
Pues esto, por un lado, creo que no hay nada más así nuevo. Por supuesto, todo se puede 00:27:30
variar mucho, pero más o menos con esto. Ya os hablé también de que los límites se pueden 00:27:39
también mostrar, por ejemplo, en PlayerController. Os enseño mi código, que es un código 00:27:49
que es bastante más complejo. Cuando empiezas... Ah, no, este no es. Este era otro que tenemos por aquí. 00:27:57
PlayerController. Bueno, capturamos las posiciones. Cosas importantes también, todo 00:28:09
lo que sea, y esto también ya sirve de adelanto para la 3, todo lo que sea coger inputs, como 00:28:21
por ejemplo aquí, que son tres inputs independientes para coger los ejes con dos teclas que unan 00:28:28
el negativo y el positivo, como ya vimos. Otro eje para el vertical, otro eje para hacer la rotación. 00:28:38
Lo suyo es ponerlo siempre en el Update, dentro del Update. ¿Por qué? Porque el Update al final 00:28:42
es la unidad de tiempo más rápida para capturar, porque según la velocidad de procesamiento, como 00:28:48
ya hemos dicho del ordenador, en cada fotograma capturará lo que estamos haciendo. Lo digo 00:28:53
porque veréis en el tema 3 que también habla de los FixedUpdate. Cuando vayáis a usar físicas, 00:28:59
ahora lo vemos, ahí sí que deberíamos usar los movimientos de AddRotate, AddTorque, AddForce, 00:29:05
en otro método que se llama FixedUpdate. Eso lo vemos ahora. Lo que quería deciros es que aquí 00:29:13
en el Update, en cada fotograma, se hizo un método, esto lo dije el otro día, lo empecé a hacer, 00:29:20
que había un montón de condiciones sobre los movimientos. Si esto llega a un punto, se convierte 00:29:25
una booleana en falso y ya condiciona que no se pueda hacer, porque recordad que las booleanas 00:29:33
sirven muchas veces para marcar que se cumpla la condición o no, que todo se puede ir agrupando 00:29:39
en métodos. Y esto es útil, por ejemplo, para lo que he dicho antes de la compañera, ir diciendo 00:29:47
voy a hacer un método que lo que sirva sea para chequear los límites. 00:29:52
Para tener claro el bloque en el que estás trabajando, yo lo referencia en el momento que 00:30:02
quiera y luego me voy a otra parte del código en la que voy trabajando en eso y luego es más fácil 00:30:07
encontrar dónde está todo que ponerlo todo en un Update. Esto ya lo hemos hablado alguna vez más, 00:30:11
pero es importante verlo. Si no hay nada más así que yo caiga, vamos a ir con la unidad 3, 00:30:16
que además había un compañero que tenía dudas sobre ello. Vamos allá. 00:30:25
Pues si quieres, coméntame qué dudas tenías para ponernos con la 3. 00:30:31
Yo creo que si me estás hablando no te digo porque te tendrás que dar al micrófono, 00:30:42
que no lo sé si estás hablando. 00:30:46
Me indica que era solo un poco aclarar cómo hacerlo. Lo primero que voy a hacer, 00:30:47
también para que tengáis en contexto lo que se pide, a nivel de más o menos cómo tiene que 00:30:57
acabar, consiste en un juego en el que hay una bola que de distintas formas tiene que 00:31:02
llegar a un agujero y meterse y entonces se pasa de nivel. Voy a hacer un poco de gameplay para 00:31:10
que veáis qué es lo que hay que conseguir. Yo tengo por un lado esta bola, que en el primer 00:31:16
nivel, por ejemplo, se moverá la bola, se impulsará ella misma hacia adelante, hacia detrás, con una 00:31:24
cruceta que he creado. Yo en mi caso el WASD, pero ya sabéis que con el Input Manager podéis definir 00:31:30
que si la bola se cae, se reinicia el nivel. Yo me caigo y pierdo. Este nivel es realmente sencillo 00:31:36
porque lo que hay que hacer es ir a ese agujero que hay allí. Cuando consigo ir al agujero, 00:31:44
lo que hace es que me cambia a otro nivel, que es otra escena que tengo aquí. Ahora ha pasado al 00:31:51
nivel 2. Ahora, en esta escena, si yo doy a la cruceta de la bola... Bueno, lo he configurado 00:31:56
así. Esto, por supuesto, por código nosotros diremos lo que sea, pero la cruceta de la bola 00:32:03
ya no se mueve. En este nivel tengo otra cruceta, que en este caso son las flechas del teclado, 00:32:07
que lo que hace es añadir un torque, una rotación por física, al tablero y entonces la bola se mueve 00:32:13
por la gravedad, según cuánto inclinemos. Efectivamente, en el nivel 2 se mueve esta base, 00:32:20
entonces el juego se complica porque hay que ir calculando un poco la trayectoria según la fuerza 00:32:28
de la bola. En las dos, si en la primera lo que se movía era la bola, con un Add Force para darle 00:32:33
empuje a la posición de la bola, en este la bola se mueve por el Rigid Body, por la gravedad, 00:32:41
pero en realidad lo que estamos usando es un Add Torque para hacer oscilar esta plataforma e ir 00:32:46
llevando la bola hacia el agujero. Y cuando llego, paso a un tercer nivel. Y el tercer nivel, que es 00:32:56
otra escena que tenemos aquí, es lo mismo. Podéis hasta usar la misma plataforma a la que le hemos 00:33:02
añadido unos bloques que sirven, como tienen colliders, para detener el movimiento de la 00:33:08
bola. Entonces, lo mismo, si yo me caigo porque la bola se cae, se reinicia ese nivel. En el anterior 00:33:13
pasaba lo mismo. Vale, me caigo porque no calcula bien, lo hago así un poco mal. Vale, importante, 00:33:20
una cosa un poco chorra, pero cuando estéis testeando, esto creo que ya lo he explicado 00:33:26
alguna vez, cuando estéis testeando en la sección Game se ejecutará todo como el juego real, es decir, 00:33:32
con los controles y las teclas y todo que hayamos configurado para jugar. Es una simulación del 00:33:39
juego. Pero nosotros podemos ir en paralelo a la ventana escena e incluso ir testeando cosas, 00:33:45
en plan, quiero ver, solo que para seleccionar tenemos que estar en este panel, quiero ver cómo 00:33:51
la bola actúa, la gravedad en ella. Si yo la echo para arriba y suelto, me lo simula. Abajo se ve 00:33:56
que se mueve porque la cámara está siguiendo la pelota, por eso está. Y si yo, por ejemplo, 00:34:03
quiero hacer una prueba rápida de qué pasa al llegar al agujero, si cada vez que queremos hacerlo 00:34:07
me tengo que pasar el nivel, que a lo mejor no, podemos coger aquí y arrastrarlo al agujero 00:34:12
directamente. Y aquí ha pasado un cuarto nivel. Este cuarto nivel es como opcional, no está 00:34:16
planteado. Lo tengo yo aquí previsto, que es igual que los otros, que si alguno llega a hacer 00:34:22
todos los niveles y quiere complicarse, se lo planteo. Es una especie de pinball que es igual 00:34:30
que el otro, pero que cuando toca estos pivotines, le añade una fuerza en la dirección que vaya, 00:34:35
coge una normal, es más complejo, y le empuja, la repele un poco. Veis que le da un poquito de... 00:34:43
Entonces con esto digamos que se puede generar como un pinball. Ahí le da, veis que le da como 00:34:51
un empuje según la orientación que tenga. Este nivel no tenéis que hacerlo para la práctica. 00:34:56
Sí que tiene una cosa importante, que lo podéis hacer ya en el nivel 3, que es el último que 00:35:03
tenéis que hacer, que cuando llega la bola aquí, lo que hace es reiniciarse el juego, volver al nivel 1. 00:35:08
Esta lógica podríamos ir haciendo niveles y niveles y niveles, que vamos enlazando escenas 00:35:13
y tendríamos un juego que podría durar un millón de niveles, según la lógica que podemos ir haciendo. 00:35:20
Hasta aquí solo ha sido el planteamiento. Si leéis bien nuevamente la tarea, se aprende mucho 00:35:28
la tarea también a ver cómo está desglosado. Son muchas cosas, a veces está organizada y tal, 00:35:37
pero bueno, se ponen pistas de cómo hacerlo, a veces se da un nuevo método, que por cierto, 00:35:43
las tareas, aunque son voluntarias, los enunciados, lo que se incluye en el planteamiento, también es 00:35:47
objeto de examen. Le digo para que también lo consideréis, que aunque no las ejecutéis, si ahí 00:35:53
se explica qué hace el Destroy, pues el Destroy también se ha visto. Entonces, dudas así que te 00:35:58
surjan. Daniel, que te veo por aquí. ¿Dudas que te surjan? ¿Has intentado empezar con ella? 00:36:07
De momento, no. 00:36:14
Yo no sé si me escuchas. Si me estás hablando, no tienes el micrófono. Le he echado un vistazo. 00:36:32
Está como en el momento... solo el tema del movimiento. Voy a hacer los primeros pasos de 00:36:39
la práctica, si no hay ninguna duda concreta. Y importante, aquí ya tenemos que ir pensando en 00:36:47
los distintos componentes, que hasta ahora tampoco había muchos, más allá de los scripts y el 00:36:53
transform, por supuesto, que son los colisionadores. Esto viene en el tema explicado, por eso, a no ser 00:36:58
que tengáis dudas concretas. Ya no me voy a detener mucho hoy, pero tenemos que ir teniendo en 00:37:05
cuenta que todo, para que un objeto pueda chocar con otro, tiene que tener un colisionador. Y para 00:37:11
que se le apliquen las leyes de la gravedad, como a esta bola, que yo lanzo el juego y va hacia abajo 00:37:16
hasta que algo lo detiene, eso significará que la bola tiene un Rigid Body. Si no, no hay fuerza 00:37:20
de la gravedad. Aparte de un Collider, por supuesto, que marca los límites. Y ojo, que yo le ponga a un 00:37:28
objeto un Collider, luego lo puedo ajustar. Yo le puedo decir que el radio es bastante más grande. 00:37:35
Y aunque la bola parezca que solo llega hasta ahí, veréis que yo cuando lanzo el juego 00:37:45
se va a quedar... o se debería quedar como flotando y de hecho está flotando un poco. 00:37:50
No se ve mucho. Veis que no, es por la perspectiva de la cámara. Pero veis que la bola se está 00:37:59
quedando estancada donde yo he marcado ese Collider. A nivel físico, los Colliders son los 00:38:04
que mandan. Que no os engañe las apariencias del Mesh Renderer, que es el renderizador de la 00:38:09
apariencia. Aquí es donde se marcan las dimensiones. Después de este inciso, en la práctica os dejé... 00:38:16
En el aula virtual tenéis un ítem al lado del enunciado de la tarea que tiene tres FBX. 00:38:26
Primeros datos importantes. Esto lo pone en el enunciado más o menos claro, pero cuando 00:38:33
incorporamos un FBX, yo ya los tengo aquí metidos, pero un FBX para incorporarlo se arrastra 00:38:40
a la sección que queramos dentro del proyecto para que se incorpore un Asset y se importa. 00:38:50
Cuando lo importamos, cuando seleccionamos un objeto, y esto por ejemplo va a ser también muy 00:38:54
importante cuando vayamos a trabajar en animaciones de geometrías 3D, en plan un personaje que se mueve, 00:39:00
o también en animaciones de objetos 2D cuando metamos Sprites en la unidad 5, cada Asset que 00:39:06
vayamos metiendo, en este caso FBX, pero igual en el futuro un PNG o una secuencia de PNGs, 00:39:14
cuando clicamos en el inspector salen opciones de ese tipo de Asset. Entonces mirad, por ejemplo, 00:39:19
cuando yo cojo una geometría, un 3D, aparte de que aquí se ve una miniatura también que podemos 00:39:26
movernos, si no se ve que esto está muy recogido, aquí se nos muestra la previa de qué es esto que 00:39:31
tenemos aquí. En este caso es una geometría de la pieza del suelo con este agujero y habrá 00:39:38
cuatro secciones que ya meteremos en ella, pero de primeras en modelo hay dos elementos bastante 00:39:47
importantes, que por defecto nos ponen una escala de 1, y hay una conversión de unidades de 1 00:39:55
centímetro a 0,01 metros en Unity. Hay una cosa, y esto puede pasar también al cambiar entre varios 00:40:02
softwares, que es que si traéis un objeto de ciertos softwares, ahora mismo no puedo decir 00:40:09
tampoco en Maya, no me acuerdo, hay softwares que trabajan en centímetros y otros como Unity 00:40:15
que trabajan en metros. Entonces lo que en un software un 1 es un centímetro, en otro es un 0,01. 00:40:21
Entonces esto, si ya nos acostumbramos a cierto flujo de trabajo, que intercambiamos modelos entre 00:40:28
softwares, pues siempre será igual porque es testearlo. Si no lo tenemos muy claro, cuando metamos la primera 00:40:37
geometría, por ejemplo, esta es la que acabo de arrastrar, que no he hecho ningún cambio aquí, 00:40:43
si yo, por ejemplo, arrastro este objeto, fijaos que yo no sé cuánto tiene que ocupar quizá, 00:40:48
pero lo primero es, cuando arrastramos un objeto, atención con ver si las coordenadas que nos pone, 00:40:54
porque lo coloca siempre en el centro donde tenemos el viewer, si son el 0,0 o donde queremos. 00:41:01
Ahora mismo igual lo vemos muy pequeño porque está súper abajo y por perspectiva parece que 00:41:06
es muy pequeño. Con estos tres puntitos lo podemos resetear, que esto creo que ya lo hemos visto. 00:41:10
Fijaos que yo tengo aquí un objeto y ahora sí que no hay 00:41:15
confusión de que esté lejos, que yo lo veo muy pequeño o no. Es decir, tener en cuenta que ya 00:41:21
hablamos que cada cuadradico del grid que tenemos aquí en el suelo, vamos, en el eje que queramos, 00:41:28
que el grid lo podemos cambiar aquí de orientación también, y se activa con este botón que hay aquí. 00:41:34
Normalmente queremos que sea la representación del suelo. Fijaos que este madero solo mide un 00:41:41
metro. A lo mejor queréis que todo sea una escala de un metro, pero es un tablero pequeñito. A ver 00:41:48
si la canica va a ser en minúscula. Y tener en cuenta que un poco las cuestiones de movimiento 00:41:55
físico, las medidas son importantes porque sí que reaccionan según las dimensiones que tengan. 00:42:02
Cuando veamos algo que no nos cuadra mucho, en ocasiones, y voy a borrar lo de la jerarquía, 00:42:09
vuelvo aquí a este material que tenemos aquí, quizás tenemos que hacer esta conversión. Yo lo 00:42:16
desmarco y cuando estamos editando assets en la jerarquía, estas opciones al final, para que se 00:42:23
apliquen, hay que darle a este Apply. Hasta que no le demos aquí, todavía no le estamos diciendo 00:42:29
que haga este cambio. De todos modos, si intentáis meter esta geometría, al meterla dice, oye, 00:42:33
en el asset hay configuraciones que no se han aplicado y lo podemos hacer aquí. Pero bueno, 00:42:39
que si lo hacemos previamente, mejor. Cancelo. No sé qué está haciendo. Me obliga a revertir, 00:42:46
por mucho que le diga cancelar. Le digo, lo aplico. Y cuando lo aplico, veis que la escala 00:42:56
ha cambiado. Ahora es así de grande y, de hecho, está orientada al revés. Ahora la escala, oye, 00:43:01
pues nos puede interesar que esto mide... A ver cuánto mide... Una burrada, porque os he dicho 00:43:11
que cada cuadrado de estos pequeños, que luego, si os alejáis, se van agrupando en conjuntos de 00:43:17
10 por 10 metros, esto mide una barbaridad. ¿Qué podríamos hacer? Bueno, pues cambiar la escala. 00:43:22
Lo que pasa es que la escala, si empezamos a tocar mucho y se ponen valores muy pequeños, 00:43:30
pueden quedar valores muy pequeños y a veces nos interesa que esté siempre en el 1, 00:43:36
para que sean siempre proporciones en relación al 1 y no haya que ir a medidas muy pequeñas o muy 00:43:39
grandes. Para eso hay otro valor aquí, que es el valor de escala. Es decir, aparte de que nos haga 00:43:45
esta conversión de valores, donde el 1 pasa a 0,01, es decir, 100 veces menos a nivel numérico, 00:43:51
aunque a nivel físico sea la misma medida, este 1 centímetro 0,01 metros. Tenemos una especie de 00:43:57
conversor de escalas fuera de la escala del transform, previo a meterlo incluso en la escena. 00:44:05
Entonces yo, por ejemplo, aquí puedo decir, esto quiero que sea una quinta parte y cuando lo aplico, 00:44:11
pues más o menos ya tiene las que yo buscaba. Este tipo de operaciones, os las indico para que 00:44:15
las tengáis en cuenta. No hay una regla en esta práctica, que si fuera un personaje o una persona, 00:44:23
pues sabemos que una persona puede medir entre 1,50 y 2 metros de altura. Y hay algo lógico. 00:44:28
Aquí el tablero, por ejemplo, yo que he puesto, mide de largo como unos 10 metros, por lo que 00:44:35
estamos viendo aquí. Y ya, pues sí, me imagino, si yo estuviera en ese escenario, pues si esto mide 00:44:42
10 metros, la bola, para que tenga proporción, que la bola sí que la creamos nosotros, pues mide 00:44:47
medio metro por medio metro. Vamos, medio metro de radio, o de diámetro, mejor dicho. 00:44:52
Ya vamos trabajando según eso. Ya veremos, estas escalas de factor en este objeto, 00:44:58
que no está animado o no tiene articulaciones, se puede cambiar y no hay mucho problema. Ya veremos 00:45:07
que si hay un rigging ya o animaciones internas, cambiar la escala de un objeto ya rigueado puede 00:45:12
modificar o afectar al rigging. Entonces pueden salir cosas extrañas. Por tanto, esto de convertir 00:45:22
unidades no debería dar problema. Esto del factor de escala no lo deberíamos tocar cuando tengamos 00:45:29
un objeto rigueado. ¿Qué es lo que habría que hacer? Pues que el modelador, o cuando estemos 00:45:34
preparando este objeto, que ya esté en las dimensiones que queramos que tenga y no haya 00:45:38
que reconvertir la escala en esto. Una vez tenemos eso, pues tenemos que generar una bola, 00:45:42
que a esta bola además le podemos poner un material. Por ejemplo, yo he hecho un material 00:45:50
que ya os enseñé el otro día, ya veremos más sobre materiales. Le he puesto un albedo, un color 00:45:57
de base de este azul y lo he hecho metálico. Bueno, podéis trastear con esto. Ya os dije el otro día 00:46:02
que para crear un material podéis crear un tipo de asset que es material y tiene los pases que 00:46:08
tienen normalmente los shaders de 3D. Luego aquí hay varios shaders, esto ya es bastante más complejo. 00:46:15
El que os pone por defecto ya os deja simular muchas cosas, como el nivel de metálico que tiene, 00:46:20
la suavidad del smoothness o cómo el especular también se refleja o no, si está pulido o no. 00:46:28
Y una vez queréis aplicarlo a un objeto, en el Mesh Renderer que tiene que tener ese objeto, 00:46:36
lo arrastráis a materiales. Así se aplica. Por ejemplo, la textura que tenemos, por ejemplo, 00:46:41
en el ítem que hay en la entrega, vienen un par de texturas para aplicarlo. Si vamos al objeto, 00:46:48
en Mesh Renderer, hemos creado un material que se llama suelo. Lo voy a buscar, yo lo creé, 00:46:58
y se llama material suelo, suelo 1. Y aquí lo que se ha puesto es un shader un poco más antiguo, 00:47:02
pero si lo pusiéramos en un shader como este, podríamos decir que el albedo sea esta textura. 00:47:12
Esta textura que tenemos aquí, que por cierto, cuando le damos a una textura que es un JPG, 00:47:21
tiene sus propios valores de edición, ya lo veremos más cuando toquemos los sprites, 00:47:26
y su Apply, que os vaya sonando, que según la naturaleza del elemento puede tener muchas opciones. 00:47:31
Pero cuando hemos metido este terreno, si generamos un nuevo material, podemos decir 00:47:39
el albedo que sea, y si le dais a estos puntitos que hay aquí, esto es verdad que no es el objetivo 00:47:47
de la práctica, tanto los materiales, pero para que sepáis cómo se haría esa textura, 00:47:56
la abro aquí, la tengo preparada. Otra cosa importante, cuando queráis, veis que yo estoy 00:48:00
intentando arrastrar este color de esta textura a un elemento que ve aquí, pero cuando yo 00:48:08
clico en la propia textura salen sus elementos. Para eso existe este candadito que tenemos aquí. 00:48:15
Si yo por ejemplo vuelvo a los materiales y digo el de acero lo voy a convertir en lo de madera, 00:48:20
necesito aquí tener los canales previstos. Puedo darle a este clic y ahora yo voy a donde quiera 00:48:26
esta textura y la puedo arrastrar a estos cuadraditos que tenemos aquí. Y veis que se 00:48:32
añade un mapa para usar en ese canal. Los canales entiendo que lo visteis ya todo en los passes de 00:48:39
render, etc. Ya lo visteis en el módulo de color. Y aquí tenemos ya un mapa que se ha coloreado azul 00:48:48
porque lo hemos tintado con este color que había puesto antes. El shader le estoy añadiendo texturas 00:48:54
aquí con el metálico. Y aquí tenemos el mapa de normales que, por ejemplo, podemos arrastrar a la 00:49:00
zona de normal map para que tenga esta rugosidad, esta simulación. Entiendo también que sabéis lo 00:49:07
que es un mapa de normales, etc. Esto ya lo veremos más en próximos temas, pero para hacer 00:49:13
una pequeña introducción. Entonces vuelvo para atrás porque esto era simplemente para hablar de 00:49:20
las texturas, pero una vez tenemos la bola, por ejemplo, en este caso lo que tendremos que hacer 00:49:25
y este va a ser el script que veremos ahora mismo. Cuando estamos generando esta bola, 00:49:31
que ya la hemos puesto, y voy a quitar el candadito para poder ver sus opciones, le 00:49:41
hemos puesto un PlayerManager, que básicamente lo que he hecho en este caso es, por un lado, 00:49:47
y ojo, esto es importante, para poder aludir. Y por eso hubo un día que os dije, atención, que todo 00:49:54
lo que vamos añadiendo aquí, estos bloquecitos con funcionalidades, son componentes, lo que 00:50:01
se llaman componentes. Y os dije, en algún momento tendremos que acceder a los propios componentes. 00:50:07
Este es el primer momento. Cuando queremos este script, está aplicado a la bola y esta bola, 00:50:12
lo voy a hacer más pequeño, tiene varios componentes y uno de ellos es el RigidBody. 00:50:18
No hablo mucho de cómo funcionan los colliders y el RigidBody porque creo que hay un vídeo 00:50:24
ya en el tema que lo explica y podéis hacer prueba vosotros, si tenéis dudas, planteadlo. 00:50:30
Pero cuando por código quiero acceder a algún campo de lo que tenemos aquí, algún dato, para 00:50:38
variarlo o tener su valor, no se puede hacer directamente. Es decir, no podemos poner aquí 00:50:44
variable ColliderSfera. Sí que se puede aludir al nombre del componente. Igual que aquí hay un 00:50:50
RigidBody, también puede haber un SphereCollider. Y veis que aquí lo que básicamente he generado 00:50:58
como variable global es una variable de tipo con el nombre de un componente. Esto es un poco raro 00:51:06
al principio, pero igual que hacemos variables float o enteros o strings o lo que sea, podemos 00:51:13
hacer que una variable sea de un tipo ya configurado por el propio software en un componente. A final 00:51:18
de cuentas tenéis que pensar que un componente es un código que ya tiene dentro muchos comportamientos, 00:51:27
muchas posibilidades. Este más, por ejemplo, en la clase RigidBody, en el código RigidBody, 00:51:32
esto es un SerializedField para cambiar. Tiene una variable, probablemente un float, por eso salen 00:51:39
decimales, de un float que se llama más. Y por eso sale igual que vosotros habéis configurado otros 00:51:46
cuando instanciabais, etc. Al final están haciendo las mismas operaciones. De hecho, si vamos aquí a 00:51:54
RigidBody, os dije que si os ponéis encima con la letra control os podéis meter dentro. Pues aquí 00:51:59
hay un montón de cosas. Esta es lo que está haciendo, que se muestra aquí ese componente y 00:52:05
que funcione de cierta forma. Y de hecho, si vamos viendo aquí, hay un public float más. Pues este 00:52:09
más lo que está haciendo con un requiebro más complejo, que es un getter y un setter, esto es 00:52:16
lo que muestra. Si yo borrara esta línea, que no lo voy a hacer porque es un método de Unity que no 00:52:22
debemos tocar, al final está configurada así. Entonces, volviendo un poco a lo que estábamos 00:52:27
viendo, podemos hacer que guardar dentro de este componente, de esta clase, que es como 00:52:34
igual que aquí hemos creado la clase PlayerManager, que es un script, en el script RigidBody, 00:52:42
en una variable que podremos usar para distintas cosas. Entonces ahora mismo estamos 00:52:48
usando una variable que apela a este componente, y ya os he dicho, podemos hacer otro que se llame 00:52:56
SphereCollider. Y ahí tenemos una variable que va a poder manejar en su interior lo relacionado 00:53:00
con lo que hay en esa clase. De hecho, esto es el principio también para si en otro script 00:53:14
de pronto ponemos PlayerManager, estaríamos hablando de este script para cambiar lo que 00:53:19
hay dentro de este script. Igual me estoy adelantando un poco, pero eso que os suene, pues igual que 00:53:23
hay un MeshRenderer, pues también habrá un Mesh. Y en el caso del MeshRenderer, que a veces 00:53:29
también tiene funcionalidades, pues eso, hay clases ya que tienen lo que vemos aquí como 00:53:40
componentes aquí esperando. Y una vez estamos aludiendo a este RigidBody, para cambiar que 00:53:44
este RigidBody se mueva en una dirección u otra, que es darle comportamientos físicos, dentro del 00:53:49
componente RigidBody hay una pestañita oculta que hay que desplegar con información de la velocidad 00:53:56
hacia dónde se mueve, que veréis que cuando yo activo, a medida que yo voy moviendo el personaje 00:54:02
o no, al final estamos añadiendo fuerzas físicas que tienen como unas orientaciones y tienen unos 00:54:11
movimientos, etcétera. Todo esto nosotros podemos indicarle que en cierto momento tenga una 00:54:18
velocidad hacia la profundidad Z de mucho, de 2, y entonces se le añade una fuerza para que el 00:54:23
objeto se comporte de esta forma. Para acceder a todas estas variables o aplicar comportamientos 00:54:30
en estas variables, hay que llegar a usar este RigidBody por código. Y aunque hayamos hecho esta 00:54:39
variable que alude ya al componente, hay que hacer lo que se dice capturar o coger el componente. 00:54:46
Y en el Start, normalmente, también se puede hacer en el Awake, ahora hablamos también un poco de esto, 00:54:53
en esta variable que ya es de tipo RigidBody, por eso no hay que volver a poner la variable, ya la 00:54:59
hemos declarado y luego decimos este RB que lo que haga es aludir al RigidBody que tiene este 00:55:04
objeto, es decir, con GetComponent y aquí dentro, otra vez, sé que es redundante, hay que poner el 00:55:12
nombre de ese tipo de componente, y esto se escribe así, hay que aprenderse esta sintaxis, 00:55:17
cambiando aquí el tipo de componente, ya tenemos acceso con RB a las funcionalidades del RigidBody, 00:55:24
lo relaciona con la física. Por eso siempre que queramos añadir una fuerza estamos haciéndolo 00:55:32
en el RB.AddForce, un método que está dentro del componente de RigidBody, pues ya como viene 00:55:38
en el tema, dándole una dirección, aquí estamos aplicando este input que tenemos aquí, para 00:55:46
decirle hacia dónde se tiene que mover, y fuerza, que son variables que se han creado previamente, 00:55:53
pues igual que para darle una speed antes al avión, pues para lo que sea, esta lo hemos generado 00:55:58
aquí como Floats, para ir dándole más o menos fuerza con respecto a lo que se ha capturado con 00:56:04
el input. Y fijaos que los input, los axis en este caso, se están cogiendo en el update, 00:56:09
pero lo que son las fuerzas físicas se están aplicando en el FixedUpdate, y vais viendo que 00:56:19
ya hay un Awake, por efecto viene el Start, el Update que ya os he dicho que se va cargando cada 00:56:27
fotograma, y luego el FixedUpdate. El FixedUpdate, viene del tema, es un cálculo que no depende del 00:56:33
procesador, es decir, si la máquina va más rápido no intenta dibujar más fotogramas por segundo, esto 00:56:39
es una proporción fija de tiempo que se va generando cada cierto tiempo que despecifiquemos 00:56:44
nosotros de manera fija. Esto de hecho, si nos vamos a los Project Settings, si no me equivoco, 00:56:51
aquí los tenemos, en Físicas no es, es en Tiempo. En Tiempo, esto también venía en el tema, 00:56:58
pero hay como que cada 0,02 haya un paso de tiempo fijo. 0,02 cada dos centésimas de segundo lo que 00:57:08
haya aquí en el FixedUpdate se va a ejecutar. ¿Y por qué no se usa el Update? Porque al final los 00:57:18
comportamientos físicos que los está generando toda la máquina, queremos que sean estables. Da 00:57:25
igual, no queremos que cuanto antes se dibuje la imagen o cuanto antes capte el Input, si tenemos 00:57:33
que esperar a que la persona le dé una tecla y lo capture, a lo mejor en el FixedUpdate si le hemos 00:57:39
aumentado ese tiempo de refresco que hay, habría un poco de lag, porque entre que le das y llega 00:57:45
a esta destrucción, porque lo hace cada dos décimas de segundo si lo cambiáramos a 0,2 en lo anterior 00:57:53
que hemos visto, no es operativo. Pero sí que queremos que capture cuanto antes lo que está 00:58:00
tocando el Input que esté haciendo el jugador, pues con el teclado, con el ratón, con lo que sea, 00:58:05
con el device que sea, pero que los cálculos físicos se hagan siempre en torno a unos periodos de 00:58:12
tiempo que ya maneja la máquina, para que sean más fiables y también estables. Entonces por eso 00:58:22
se disgrega, por un lado se está cogiendo este MoveV, MoveH, y luego se aplica aquí. También 00:58:26
hay otro método que se puede escribir que es el Awake. Recordad que el Start es cuando arranca 00:58:35
el script, solo una vez ejecuta lo que hay aquí dentro y ya no más, como pasaría en el Update. 00:58:42
El Awake es antes de que se ejecute ese script, cuando ya se está arrancando el juego, pues ya 00:58:50
podemos poner instrucciones que estén precargadas. ¿Esto para qué sirve? Por ejemplo, si yo quiero 00:58:56
desde un objeto aludir, por ejemplo, al instanciar en la práctica 1. A ver si doy un buen ejemplo. 00:59:02
Si yo cuando instancio no arranco el script y no, digamos, le asigno la variable aquí, 00:59:13
es decir, si aquí le digo coge este objeto que le he puesto por SerialIceField, lo declaramos aquí 00:59:20
en el Start, hasta que no se arranque este script, no hace esa operación de asignar el objeto. 00:59:26
Imaginaos que otro script alude al objeto que hayamos capturado en este script. Como no está 00:59:36
cargado hasta que lo lancemos, si ese GameObject no está activo, no sabe dónde buscar. Pero si 00:59:45
está precargado, sí, porque independientemente de que se lance o no, de que se ejecute el objeto, 00:59:50
el GameObject, el script ya tiene algo dentro. Entonces a veces hay operaciones que es normal 00:59:57
hacer en el Awake. Y luego hay otro de los básicos, hay alguno más por ahí, que es el 01:00:02
VoidLateUpdate, que se ejecuta después de todos, vamos, de los últimos. Esto, por ejemplo, se usa 01:00:08
para los seguimientos de cámara que ya hemos hecho en algún momento, por ejemplo, con el avión. Y por 01:00:16
ejemplo, todo el seguimiento que haga la cámara de otros objetos, porque es dependiente de lo que 01:00:21
hagan otros objetos en su Update y en el FixedUpdate, es preferible que haga bien el cálculo ya una vez 01:00:26
se ha calculado el resto de elementos en el FixedUpdate. Porque teniendo en cuenta que el Update 01:00:33
es común a todos los scripts que tengamos, todos irán ejecutando lo del Update en cada fotograma. 01:00:37
Entonces, en este paso, cuando todos los Updates de todos los programas hayan hecho sus operaciones, 01:00:43
le decimos, ahora, antes de que llegue el siguiente fotograma, rápidamente ejecuta lo que hay aquí, 01:00:49
si es, por ejemplo, la posición de la cámara que siga a otro objeto. Pues ya se ha calculado 01:00:55
correctamente todo para ya hacer ese seguimiento. De hecho, lo tengo aquí preparado. Si buscáis, 01:00:59
esto también creo que os lo he dejado por ahí, si no, os digo cómo buscarlo. Si ponéis en Google 01:01:09
orden de ejecución en Unity, bueno, nos lo ha puesto en la versión 2019, es igual, en la siguiente, 01:01:15
en los manuales de Unity, mirad que también a veces se puede filtrar por qué versión. Como 01:01:28
estamos usando la 2020.3, la más cercana de estas es esta. Y aquí hay una infografía que va diciendo 01:01:34
por orden, de arriba a abajo, el orden de ejecutado que os estoy diciendo. Empezaría con el Awake, 01:01:42
incluso antes de que se inicialice el editor o según arranca el editor. Luego, ya el Start, 01:01:48
cuando se inicializa el Script. Y así podemos, el Fixed Update, que no es que se ejecute antes 01:01:54
que el Update, aunque esté más abajo, sino porque como es algo estable, cada cierto tiempo van un 01:02:01
poco en paralelo, porque a lo mejor el Update va más rápido o menos rápido, pero este sí es fijo. Y 01:02:08
aquí se van ejecutando ciertas acciones, algunas como el OnTrigger y el OnCollision, pues ya lo 01:02:13
vamos a usar en esta práctica. Hay distintas, el Update, aquí se calculan muchas cosas y cuando 01:02:18
ya calcula todo hasta aquí, el LateUpdate, lo que os acabo de decir. Y luego hay otras operaciones, 01:02:24
pues como de cierre, los Destroys, que no es exactamente el Destroy que os he comentado antes, 01:02:29
pero algo tiene que ver para cerrar la aplicación, para destruir también la aplicación a nivel 01:02:34
de ejecución. Aquí tenéis el orden y ese orden es importante por lo que estamos viendo. Ya en este 01:02:41
punto empieza a serlo. Por eso, todo lo que sea captar Inputs lo haremos en Update, todo lo que 01:02:47
sea aplicar fuerzas o cuestiones físicas, que haya un movimiento físico, un cálculo físico, lo suyo 01:02:54
es hacerlo en el FixedUpdate. En el Update va a funcionar, pero aquí es donde va a estar mejor 01:03:00
calculado. ¿Hasta aquí qué tal? Sé que estoy contando bastantes cosas, aunque varias estaban 01:03:06
ya en el tema. De hecho, muchas y otras ya las había contado Álvaro en el vídeo. ¿Qué tal? ¿Me 01:03:12
vais siguiendo? Es decir, eso es que me vas siguiendo. Bueno, hemos puesto que entiendas 01:03:19
un poco. Por eso tampoco quiero ir muy adelante, porque hasta que no os pongáis... Os leáis el tema 01:03:29
lo primero, veáis los vídeos que hay ya y os pongáis a encarar la tarea, no vais a ir viendo 01:03:37
cómo funciona esto. Para que os hagáis una idea, os dejo el de la bola, porque luego el de la tabla 01:03:43
es igual con un torque, pero se aplicaría igual. Habría que capturar el RigidBody y luego ya 01:03:50
podremos, con el punto que marca, que permite ver los métodos y lo relaciona con las físicas que 01:03:56
hay dentro del componente RigidBody, pues aquí estoy añadiendo esta fuerza con la dirección. 01:04:04
Esto lo pone en los apuntes. Aquí lo que estamos haciendo es, lo primero, en el Start, cuando 01:04:09
se empiece el script a ejecutar, quiero que en todo momento haya una variable que está accediendo al 01:04:18
RigidBody de ese objeto. Porque como no estoy diciendo que sea de otro objeto, que esto 01:04:24
también se puede hacer, me estoy refiriendo al RigidBody del mismo objeto. Igual que cuando 01:04:28
ponemos transform, estamos hablando aquí transform position. Aquí no hay que hacer esto de GetComponent 01:04:32
porque hay una especie de atajo para hablar de este transform sin tener que capturarlo, pero 01:04:39
habla del transform de este objeto. Pues igual, aquí ahora al coger el componente, que, ojo, tiene que 01:04:45
estar aplicado, tiene que haber un componente RigidBody, dice, vale, pues en RB ya puedo acceder a 01:04:51
todo lo relacionado con este componente. Y posteriormente, en el Update, pues igual que hemos 01:04:58
hecho con la nave, guardamos en una variable los inputs y posteriormente hacemos la mezcla de los 01:05:03
dos ingredientes en donde se calculan las físicas. Y decimos, dentro de ese RigidBody, vamos a aplicar 01:05:11
una fuerza o atorque, si lo que quisiéramos es que haga una rotación. Y aquí tendremos que decirle, 01:05:16
en esta dirección, según cuánto estemos metiendo de input, recordad que en un Axis, si no estamos 01:05:22
pulsando nada, es cero. Si pulsamos la tecla del eje positivo, será uno, o si es la negativa, 01:05:28
menos uno. Igual que hicimos con la nave. Por una fuerza, que es este valor que hemos metido 01:05:37
en una variable global. Entonces ya con esto, por ejemplo, tenemos que la bola se va moviendo. 01:05:42
Importante, error típico. Cuando hagáis el seguimiento de la bola, en este caso, tened 01:05:57
en cuenta que al ser una bola, está rotando. No se nota mucho, pero está rotando. Si luego 01:06:02
ponemos que la cámara, como hacemos aquí, siga con un Offset, como hicimos en la nave, 01:06:07
siga con un Offset a la bola, tened en ojo que lo que tiene que seguir es el Transform, 01:06:13
pero la posición, no la rotación. Porque si decís que siga la rotación, fijaos que yo selecciono 01:06:23
la bola y yo cuando mueva, está cambiando la rotación. Si hacemos que la cámara siga la 01:06:28
rotación, va a empezar a moverse para todos lados. Os lo enseño aquí rápidamente. 01:06:34
No me gusta enseñaros mucho los scripts hasta que lo probáis vosotros, porque si no, 01:06:42
intentáis solo copiar el código y tampoco es lo suyo. Fijaos que aquí lo que va a hacer es, 01:06:49
ponemos el decalaje como la otra vez, pero lo que va a ir moviendo es el Transform.Position, 01:06:58
no el Transform a pelo. Va a haber un Transform.Position y no la rotación. Donde se mueva 01:07:02
la bola, allá que va la cámara, con este decalaje que tenemos aquí, con el Offset, que es igual que 01:07:11
el que hicimos el otro día en la última tutoría. Y aparte, aunque en esta no es tan importante, 01:07:16
pero en las siguientes escenas sí, ya se ve en la teoría también el método de Transform.LookAt, 01:07:22
que es que la rotación va a ser dependiente de donde esté la cámara, donde esté el objeto que 01:07:29
sigue, que en este caso es la bola. ¿Esto qué significa? Que, por ejemplo, en el nivel 2... 01:07:35
Escenas, nivel 2. Yo no sé qué he cambiado, yo creo que nada importante. Aquí tenemos la cámara 01:07:46
con un Offset y se va moviendo con la cámara, pero si la bola rotara o se moviera, la cámara 01:07:55
siempre está orientando. Por ejemplo, veis que aunque la posición vaya bajando o subiendo, 01:08:02
la cámara siempre está intentando enfocar hacia donde esté la bola. Con LookAt, la rotación de 01:08:07
la cámara será dependiente a donde esté la bola. Ahora está tan rígido que está siguiendo la bola 01:08:14
como si fuera una especie de grúa que sigue a cierta distancia, pero podemos hacer que en vez 01:08:23
de seguir exactamente la posición con un decalaje, esté donde esté la bola, se vaya orientando hacia 01:08:30
donde esté ahí. Entonces siempre mira la cámara desde su posición hacia donde esté la bola y 01:08:38
cambiaría la posición. Si queréis, lo hago en un segundo. Me meto en el Script, lo abro a ver qué 01:08:43
está por aquí. Este no es. A ver, tampoco. Aquí. Imaginaos que yo le digo el Transform Position 01:08:50
que no se mueva, es decir, le voy a decir, ojo, la bola se va a mover, lo voy a comentar, pero 01:09:03
realmente en el Fixed Update, y aquí la verdad es que no sé por qué puse Fixed Update, sería 01:09:11
explicándolo o algo así, es en el Update, o mejor aún, como os he dicho antes, en el Late Update, 01:09:18
lo que estamos haciendo es, bueno, aquí hemos generado una variable Posición 3 que me da el 01:09:24
decalaje, las coordenadas de dónde debería estar la cámara con ese decalaje y luego se lo aplicamos 01:09:30
al Transform. Ahora mismo esto no hace nada puesto que no está afectando al Transform y lo que hemos 01:09:34
hecho aquí es que la cámara esté mirando a la bola. Ahora lo que vamos a conseguir es que desde 01:09:39
su posición, vais a ver que cuando se va moviendo la plataforma, si veo las coordenadas de posición, 01:09:45
la cámara no se está moviendo como pasaba antes, sino que lo que va a ir es orientándose hacia 01:09:55
donde esté la bola, desde su posición, ni sube ni baja. Entonces si baja, por ejemplo, la bola, 01:10:01
pues la cámara... No hay muchos objetos que dé en perspectiva de... Habría que poner un fondo o 01:10:06
otros objetos para saber qué es arriba y abajo, que ahora mismo no es muy claro, pero es la cámara... 01:10:11
Vuelvo a ejecutarlo aquí. Realmente no se está moviendo como pasaba antes, sino que rota para ir 01:10:17
siguiendo ese objeto. Para eso sirve el LookAt, simplemente que os suene porque a veces es muy útil. 01:10:23
Aquí, a ver... Late Update va mejor, como os he dicho antes, para la cámara y el Transform. 01:10:28
No sé si algo más para empezar. Podéis seguir. Una cuestión más es los OnTriggerEnter, 01:10:36
los OnCollider, pero intentad hacerlo vosotros con lo que ya se ve en el tema. Para el próximo 01:10:47
tutorial, planteadme dudas y si os encontráis con dudas, me las indicáis, porque lo que habrá 01:10:55
que hacer es... Voy al nivel 1, que se ve un poco mejor. En el nivel 1, por ejemplo, claro, hay que pensar 01:11:01
dos cosas. Primero, que cuando la bola se caiga, hay que decirle de algún modo, oye, cuando se caiga 01:11:10
la bola, pues hay que reiniciar el nivel. Para eso, en el precipicio, se ha puesto un Collider, es decir, 01:11:17
se ha creado un objeto nulo y solo se ha puesto un BoxCollider. Aquí no hay MeshRenderer, no se ve nada. 01:11:26
Es lo contrario que he dicho antes. Aquí no hay apariencia, aquí es solo un área que hemos definido, 01:11:31
con un área que lo que hace es que cuando caiga la bola y entre aquí, se desencadena acción. 01:11:37
Para eso son, por código, los OnTrigger y los OnCollisionEnters. Son métodos que existen. 01:11:43
Importante, cuando tenemos un Collider, 01:11:50
por ejemplo, aquí voy a añadir otro, un SphereCollider, uno con forma de 01:11:57
esfera. Voy a poner SMSCollider, lo voy a ubicar cerca de la bola. 01:12:04
Veis que aquí tengo otra esfera que se controla en sus coordenadas desde el propio 01:12:14
componente del Collider y voy a poner 01:12:20
que este, perdón, que como lo estoy metiendo en un objeto que está abajo, es complicado ajustarlo. 01:12:27
Dejo ahí la bola y lo que os decía, tengo este Collider que lo voy a poner justo debajo 01:12:35
de la bola. Lo muevo para que esté justo debajo de la bola. Entonces yo cuando lance el juego, 01:12:46
por defecto, la bola se queda ahí y lo detecta. Eso es una malla. La cosa es que cuando por defecto 01:12:53
metemos un Collider del tipo que sea, viene así. Podemos cambiar las coordenadas, el radio, 01:13:02
según el tipo de Collider puede tener opciones distintas. Pero hay una opción común a todos que 01:13:08
es esta de IsTrigger y esto creo que es algo muy simple pero que a veces cuesta entender. Si no 01:13:14
está marcado, que es como viene por defecto, ya lo veis, esta malla sirve para que choque las cosas 01:13:21
con ella. Por ejemplo, lo que habéis visto que ahora mismo está colisionando en el sentido de 01:13:27
que choca con ella. Pero es que los Colliders también se usan para definir áreas que desencadenan 01:13:31
cosas pero que no necesariamente tienen que tener una apariencia física de que algo choque con ello. 01:13:37
Por ejemplo, si yo ahora mismo a este Collider le dijera IsTrigger, vais a ver que lo atraviesa. 01:13:43
Uy, espera, aquí está pasando algo, un segundín. 01:13:53
Vale, sí, ya sé lo que está pasando. Básicamente tengo que desactivar donde estábamos, en precipicio. 01:14:01
Imaginaos que no está este script todavía, que hace otras cosas. Lo que estaba pasando es que 01:14:09
cuando atraviesa esto se estaba reiniciando el nivel, que es lo que he dicho que pase cuando 01:14:13
toque esta caja. Vuelvo a darle. Ahora, el Sphere Collider... 01:14:17
Vale, sí, lo que pasa es que se sigue haciendo de todos modos. 01:14:23
Move up el componente. 01:14:32
Debe haber otro otro punto por aquí que está haciendo que cuando toque el IsTrigger de esta 01:14:37
esfera se ejecute lo que tengo en precipicio. Voy a hacer otra cosa que igual es lo que debería 01:14:44
haber hecho. Voy a eliminar este Sphere Collider que le he puesto de muestra, lo borro, como si no 01:14:53
hubiera pasado nada. Voy a generar un cubo muy rápido, que lo pongo en el 0,0 para que esté por 01:14:58
ahí. Ese cubo ahora es visible porque, por defecto, viene con un Mesh Renderer. 01:15:05
Lo que os he dicho, el Mesh Renderer da la apariencia, pero yo no la quiero. Cuando creamos una 01:15:14
primitiva, tiene este Collider ya activado sin el IsTrigger y vais a ver que se 01:15:19
queda ahí flotando la bola porque detecta esa superficie. Si yo lo pongo en IsTrigger y la 01:15:26
lanzo, vais a ver que la atraviesa. Aunque hay un Collider, no existe. Y IsTrigger significa 01:15:31
disparador, como para disparar. En una pistola el trigger es el gatillo. Esto sirve para decir 01:15:39
que cuando la bola pase cierta área que hemos marcado con un Collider, decirle que ha atravesado 01:15:46
una puerta o se ha caído la bola y cuando llega aquí abajo es que ha perdido, que es lo que hemos 01:15:52
hecho en el precipicio. Y aquí hay un script, IsTrigger, es decir, cuando la bola llegue hasta aquí 01:15:56
abajo no va a colisionar con esto, va a seguir bajando, pero sí que atraviesa un área que nosotros 01:16:02
detectamos para hacer otras acciones. Si yo, por ejemplo, enseño este precipicio, aunque tiene 01:16:07
cosas más avanzadas, lo que me importa, que viene en el tema también para que investiguéis, es que se 01:16:13
puede crear, igual que un Void Start, un Void Update, como viene el Void Awake, que os he dicho 01:16:19
antes, hay otro tipo de Voids que son los OnTrigger. Y hay un OnTriggerEnter, es decir, en cuanto un 01:16:24
objeto entre en un área que tenga un trigger, es decir, un Collider, con esto activado de trigger, 01:16:31
pues yo puedo decirle en cuanto toque esto hago tal, que en este caso es que se reinicie el nivel. 01:16:37
Esto lo hablamos otro día, viene en los apuntes nuevamente, pero hoy si no nos alargamos mucho. 01:16:43
Cuando entre, puedo decirle también que sea cuando salga, o si pongo OnTriggerStay, es el 01:16:49
tiempo que esté aquí dentro, que se ejecute lo que hay aquí. El tiempo que en este caso otro Collider, 01:16:56
como el de esta bola, esté tocando este OnTrigger, podemos decirle que haga órdenes. Por ejemplo, 01:17:03
estamos en un nivel con puertas y que al atravesar una puerta se active, que suene 01:17:09
una alarma. Para que detecte eso, el personaje tendrá un Collider, que aparte de servir para, 01:17:18
si no es trigger, para que tenga un pie que se posa en el suelo y no le deja pasar, sirve que 01:17:24
ese Collider atraviese otro que hemos puesto la puerta, que ese sí que es trigger, para que detecte 01:17:32
que estás pasando la puerta y ya desencadenar, por ejemplo, el sonido de una alarma. Ahí ya, 01:17:37
nuevamente en el código, iremos especificando qué hace. Esto de ElixTrigger es esencial para ir 01:17:42
gestionando que cuando ocurra algo, como por ejemplo, queremos que llegue a este agujero. Si os 01:17:50
fijáis, yo tengo aquí un elemento que se llama Goal, que no tiene MeshRenderer, no se ve nada, 01:17:56
pero si vamos aquí, el Goal es, y me meto en el agujerín, vais a ver que cuando la bola se mete, 01:18:01
cuando llega a este trigger que está marcado por ese cuadrado, cuando la bola toca ese trigger, 01:18:07
dice, pues hay que cambiar de nivel. Y este es el funcionamiento, por ejemplo, 01:18:14
para cambiar de nivel. Yo tengo aquí un script que dice, me meto. Cuando algo entre en el trigger 01:18:18
que tengo, si el otro objeto, esto ya lo veremos, es la bola, si el nombre es la bola, pues lanza 01:18:26
otra escena. Entonces, ese es el funcionamiento del OnTrigger. También existe otro método muy 01:18:34
parecido, que es el que se llama On. Y esto de OnTrigger, no hace falta que escribáis todo, 01:18:41
si empezáis a escribir OnTrigger, ya os salen las opciones. Y ojo, si no estamos trabajando en 2D, 01:18:47
que no es el caso todavía, siempre el que no pone 2D, que veréis que hay muchos. Por ejemplo, 01:18:52
el OnTriggerEnter. Pues empiezo. Me lo ha escrito ahí. ¿Y por qué no sale el OnTriggerEnter y sale 01:18:57
en el resto? OnTrigger. A ver. OnTriggerEnter 2D. Ah, vale, porque como ya hay un OnTriggerEnter, 01:19:05
no se puede escribir otro. Si no existiera este OnTriggerEnter, si, por ejemplo, yo pongo aquí 01:19:13
Stay, que es el de permanecer dentro, OnTrigger. Empezáis a escribir y ya le dais aquí y os lo 01:19:18
completa. Incluso os abre las llaves. Hay otro tipo que es el OnCollision, Enter, Exit, Stay, 01:19:23
también con su versión en 2D, que eso significa que si este Collider no lo hemos marcado, por ejemplo 01:19:35
el de la bola, como trigger, es decir, que sí que lo percibe una superficie con la que choca en el 01:19:41
juego, también se puede decir que cuando choca algo no lo va a atravesar. Cuando choca, que 01:19:48
desencadena en otras opciones. Por eso hay otro muy parecido, pero que no es exactamente igual, 01:19:54
que es este que os estaba comentando de OnCollision. A ver dónde tengo yo este escribido. Ahora, 01:19:58
¿qué estaba escribiendo? El OnTriggerEnter. A ver, que tengo aquí un buen jaleo. 01:20:02
Este que tenemos aquí. El OnCollision, igual, cuando choque con el objeto, cuando choque y 01:20:10
deje de chocar, que sería el Exit, pues el Enter, y os crea esto. Ya veremos lo que son estos 01:20:19
argumentos que pasa aquí, entre paréntesis, porque con esto podemos decir que el objeto que haya 01:20:25
chocado, si se llama de tal manera que sea el que haga las acciones. Podemos hacer condiciones 01:20:31
más avanzadas. O que cuando choque un objeto con este, si el que choca tiene una etiqueta de 01:20:36
enemigo, pues entonces sí que se muere el enemigo. Si lo que choca es la bala, pues que entonces se 01:20:43
incruste. Entonces podemos ir discriminando qué acciones. Pero creo que ya, si os sigo hablando 01:20:53
más por hoy, y más si nos habéis puesto a hacer la tarea, solo voy a quemar la cabeza. 01:20:57
Más información www.alimmenta.com 01:21:06
Subido por:
Daniel M.
Licencia:
Todos los derechos reservados
Visualizaciones:
45
Fecha:
25 de enero de 2024 - 20:04
Visibilidad:
Clave
Centro:
IES CIFP a Distancia Ignacio Ellacuría
Duración:
1h′ 21′ 09″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
727.94 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid