Vídeos UT2 - #3 - DEIM - Curso 25·26 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
Vídeo de apoyo a la UT2 de módulo DEIM
fijaos en este código que yo tengo aquí distintos métodos no sé por qué aquí me
00:00:07
ha dado error ahora no debería bueno sí porque tiene falta otra línea de
00:00:12
comentario vale ahí lo dejo yo voy viendo que aquí tengo un montón de
00:00:16
métodos preparados pero cuando sale además con esta palabra en gris vamos
00:00:22
gris es amarillo pero está como sombreado significa que no está
00:00:27
usándose pero yo tengo este código aquí preparado por si lo que quisiera usar e
00:00:31
Incluso veréis que cuando tenéis un script, y fijaos también en el número de las líneas, tenéis hasta flechitas para reducir, para ir compactando estos scripts.
00:00:35
Así de primeras a lo mejor no es lo más óptimo, pero si dice, vale, estos no los estoy usando, pero los quiero aquí.
00:00:48
Fijaos que hay saltos de línea y los habéis encogido.
00:00:53
Estos son códigos que yo tengo aquí comentados porque no quiero usar, porque a lo mejor los he probado y no me funcionan,
00:00:55
o porque es una funcionalidad que no tengo claro si va bien o si la voy a usar.
00:01:00
Bueno, yo puedo tener un montón de métodos, por ejemplo, aquí preparados
00:01:04
Entonces podéis comentar y llegar de distintas formas
00:01:09
Así que es verdad que para las entregas intentad dejarme la solución
00:01:14
Sin mucha, lo voy a decir así rápido, morralla
00:01:18
Porque si no me vuelvo loco de qué estáis intentando entregar
00:01:20
Y otra cosa importante es en las tareas
00:01:23
Y vais a ver que ya son amplias y se piden muchas cosas
00:01:28
Os pido por favor que intentéis resolver lo que se os pide en la tarea
00:01:30
luego vosotros si queréis complicar las todo lo que queráis o seguir pues por supuesto hacerlo
00:01:33
pero de cara a la tarea no uséis por ejemplo si se pide el input manager no uséis el input
00:01:38
system que es bastante más complicado el input system por ejemplo se explica para que lo conozcáis
00:01:44
y porque es relevante pero con todas las cosas que hay que dar no no es asumible pasar mucho
00:01:48
tiempo con el input system pero hay tantas cosas que vamos a ir a por lo que hay que sacar vale
00:01:54
Que no es poca cosa, ¿vale?
00:01:58
El otro día, entiendo que todos los que lo habéis hecho,
00:02:00
lo que habéis, la que le estáis entregando, la estáis acabando,
00:02:03
básicamente lo que habéis hecho es usar el método rotate del transform, ¿vale?
00:02:06
Como aquí, ¿vale?
00:02:09
En base al eje Z, los que dijimos que gira en base a ese eje, ¿vale?
00:02:10
Entonces, pues rotará hacia los lados realmente con el eje Z.
00:02:15
Y bueno, pues con lo que se va capturando de los inputs, ¿vale?
00:02:19
Que ya, bueno, pues hablamos de los axis y cómo crearlo y ese menos uno y uno como límites de un eje entre un valor positivo y negativo para transmitir esa información, ese dato, por ejemplo, a un cambio de posición o de rotación, ¿vale? Esto era una forma de hacer que la nave rotara.
00:02:26
Y de hecho, yo si comentara todo esto hasta aquí, y este es el método que estoy usando, entonces con este rotate, básicamente, esta nave, si le doy hacia la derecha, rotará indefinidamente, si doy a la izquierda, rota indefinidamente también.
00:02:44
Y además, como el transform lo hemos puesto, recordad, el translate, perdón, como que use el espacio, el mundo, en vez del self, recordad esto que teníamos por aquí, que el space sea el world y no el propio objeto en sí, pues da igual lo que giremos, que siempre el arriba va a ser el arriba del mundo o el abajo del mundo, etc.
00:03:03
¿Vale? ¿Qué ocurre? Que a lo mejor, y yo en mi planteamiento seguramente sería este al hacer el juego, es que la nave rote hasta este punto o hasta este punto, ¿vale? Y no pase de ahí. ¿Qué ocurre? Que no estamos haciendo ningún límite para que esto deje de hacerlo así.
00:03:27
Entonces ahora la nave de pronto la podemos poner boca abajo o boca arriba, o como nos dé la gana, porque rota indefinidamente y ya está. Aquí no se pedía explícitamente que limitáramos esos movimientos, pero os quería contar un par de cosas sobre cómo se podría hacer, porque también nos da ideas de cómo podríamos hacer esto.
00:03:42
Voy a poner la otra, que es una muy simple realmente y vais a ver que ahora mismo he activado otro método que tenía aquí de rotar nave, que si bajamos hace una cosa muy simple y que vais a ver cómo funciona.
00:04:02
Lo que estoy consiguiendo es, en el update, recordad que esto está dentro del update, voy a ampliar esto para que se vea más, en el update lo que estoy diciendo es que, y recordad que los ángulos en Unity, si usáramos lo que a priori sería lo lógico, que es un parámetro que se llamara rotation, igual que hacemos position, si usamos rotation, y bueno, lo pone en el propio tema, etc., está usando esta clase quaternion,
00:04:15
que se basa en cuatro ejes, que es poco comprensible para el ser humano, aunque tiene su explicación de uso, etc.
00:04:44
Y nosotros nos deberíamos ceñir más a lo que son los ángulos Euler, que se basan en grados, en degrees, y se basan además en tres dimensiones.
00:04:50
Hace una traslación, si me meto en el transform, nuestra forma de entender la rotación en los software 3D, etc., se basan en estas tres dimensiones.
00:05:01
Entonces, digamos que lo que hacemos aquí es decir, vale, pasamos, entre comillas, queremos que la traslación del quaternion la usemos dentro de esta forma que nosotros sabemos usar,
00:05:10
que son estos tres ejes de X y Z, y le vamos a decir, básicamente, que la posición o el valor que tengan estos ángulos Euler recojan un vector nuevo que estamos creando en ese momento,
00:05:26
que no interfiera, es decir, que siempre mantenga en cero la rotación de X e Y,
00:05:38
porque no nos interesa, porque la nave no va a inclinarse hacia abajo
00:05:44
ni hacia... no sé cuál sería el otro eje.
00:05:47
Que haga un derecha-izquierda en el sentido de que lo haga en torno al eje Y.
00:05:51
Entonces, el que nos interesa en esta práctica, porque lo que estamos pidiendo
00:05:55
es que rote en torno al eje Z, ¿verdad?
00:05:59
Entonces, podemos decir, vale, lo que vamos a hacer es poner un rotate data,
00:06:02
que básicamente es este input axis, que puede dar como máximo 1 o menos 1, recordad, según los dos extremos, y multiplicarlo por 90 o por menos 90.
00:06:06
Bueno, podría ser 90 o menos 90, cuando se invierten a veces los valores es simplemente porque el eje ya es o positivo o negativo,
00:06:17
si vemos que va en la dirección contraria a la que nos interesa, como al final esto lo que está dando es valores de rotación,
00:06:26
que queremos que vayan hacia un lado que es positivo o negativo,
00:06:31
aunque esto luego os voy a contar que tiene trampa, ¿vale?
00:06:34
Va entre o a 90 o a menos 90, ¿no?
00:06:37
Entonces, si es 1, pues será menos 90, si es menos 1 será más 90, ¿no?
00:06:40
Y, bueno, pues si ponemos este menos es porque nos interesa invertir la dirección, simplemente.
00:06:45
¿Qué significa esto?
00:06:49
Que si pulsamos en un teclado, que además un teclado, como ya hemos hablado,
00:06:51
no es como un gamepad, un joystick, que tiene un recorrido entre el 0 y el 1, ¿no?
00:06:55
en esa mitad del eje, sino que es pulsar una tecla y es de pronto 1, de pronto 0 o de pronto menos 1, si es la del eje negativo,
00:06:59
pues de un momento a otro, porque esto es en el update, de un fotograma al siguiente, de pronto se encuentra que es o más 90 o menos 90.
00:07:06
Si ahora tengo activado este RotarNave, y os vuelvo a decir, si veis que está el nombrecito en amarillo vibrante,
00:07:14
significa que esto lo está usando, si nos ponemos encima, lo está usando algún punto del código.
00:07:21
Si tenemos aquí preparado y está así desvanecido, significa que está preparado, está planteado este método, pero no se está usando.
00:07:25
Problema y beneficio que hemos encontrado con esta solución de una línea.
00:07:36
Ahora sí que conseguimos que la nave solo va a rotar hacia un lado, cuando suelto, como no estoy dando ni más uno ni menos uno, sino que es cero,
00:07:40
Se vuelve a su posición estática, ¿vale? Y fijaros en el Z, en la rotación de Z, si yo giro hacia la izquierda, pues es 90, suelto, es 0, doy al botón de la derecha y es menos 90, ¿vale? Lo que no hay es valores intermedios. Hace esto, que es así, de rápido.
00:07:51
¿Qué pasa? Que hay una forma, y así también entendéis este concepto, hay una forma de, digamos, al pulsar un input, aunque sea una tecla que da un valor de 1 o menos 1 repentino, recordad, y si veis los apuntes lo pone, que cada uno de estos, ¿vale?
00:08:10
es el que me interesaba, que fuera específico de esto, ¿no?
00:08:40
Que era el rotador, el eje que recogía este rotate data, ¿vale?
00:08:43
Que yo lo he creado y le he dicho, vale, cuando pulso, yo he puesto estas teclas,
00:08:47
cada uno puede poner las que considere, ¿vale?
00:08:53
Aunque, bueno, poner unas lógicas también para un juego, ¿vale?
00:08:57
Yo estas, si poner la mano derecha en la U y la I, más o menos tiene ese espacio
00:09:01
para la cruceta del WASH y para la rotación, para esta rotación en este caso.
00:09:05
Valor negativo para que vaya a la izquierda la U, para que vaya a la derecha la I latina.
00:09:10
Y tenemos estos valores de Gravity y Sensibility.
00:09:14
Y si nos ponemos encima es, por un lado, la sensibilidad,
00:09:18
sensibilidad, mejor dicho, que tiene el input según se pulsa hasta que llega a su valor máximo,
00:09:22
que sería este 1 o más 1, más 1 o menos 1, y hay de 1000, es súper rápido.
00:09:29
Pero eso no significa que yo este valor no lo pueda cambiar. Esto significa que si yo le digo que la sensibilidad sea de 5 y lo pruebo, ahora vais a ver que yo le doy al play que va a llegar a ese más 1 y menos 1 de una forma progresiva.
00:09:33
Al soltar veis que vuelve, al volver a relajar y que sea el cero, vuelve inmediatamente, pero veis que con esto ya hemos conseguido que los valores máximos y mínimos sea porque aunque sea una tecla el input haya un cierto periodo de, digamos, de interpolación, no es la palabra, de recorrido hasta llegar a ese punto.
00:09:54
Lo mismo pasa si lo alteramos aquí con la contraria que es al soltar cuánto tiempo vuelve a la situación de origen.
00:10:15
Si yo en gravedad pongo 5, por ejemplo, un valor mucho más pequeño que este 1000, lo que vamos a conseguir es que aparte de que cuando giremos haya esta interpolación,
00:10:26
Cuando soltemos y vuelva al valor neutro
00:10:36
Porque ahora hay un valor neutro de 0
00:10:39
Cuando no estamos pulsando nada
00:10:40
Veis que vuelve a ese valor relajado
00:10:42
Entonces, bueno, aparte de subir, bajar, ir a la derecha, etc
00:10:45
Pues tiene esta interpolación
00:10:49
Y, ojo, tiene unos límites
00:10:50
Ahora no hace este giro continuo
00:10:52
Que teníamos en la anterior opción
00:10:55
Esto siempre es según lo que se busque
00:10:57
A lo mejor en el juego quiero que la nave rote sin parar
00:10:59
Pero, bueno, es una forma también para que veáis
00:11:01
Que aunque usemos teclas
00:11:04
Hay valores relacionados con que no sean repentinos estos inputs. Esto es una solución para llegar a estos límites máximos usando esta suavidad de los inputs.
00:11:06
Hay otra solución más compleja, por ejemplo, otra alternativa, y aquí es donde voy a comentar este método y voy a poner esto de rotarNav y fijar, que es la que antes había comentado.
00:11:33
Que básicamente es seguir empleando, por poner un valor que hemos creado aquí una variable para que sea más o menos rápida, este rotate. Solo que se han añadido unas cuantas líneas más para que ese rotate también tenga una limitación de esa rotación.
00:11:46
Y esto lo voy a explicar para que veamos la trampa que tienen estos Euler angles, porque al final lo que estamos variando a veces, aunque estemos viendo una cosa en el inspector, cuando vemos aquí esta nave que vaya girando en Z, realmente la traslación de los Euler angles no es tal.
00:12:04
Me explico, yo si cojo esta nave y empiezo aquí a girarla con el inspector y empiezo a girar, a girar, a girar, veis que hay valores que superan los 360 grados que tiene una rotación completa y que es que cada 360 grados básicamente está volviendo a empezar otra vez la rotación.
00:12:26
Creo que hasta aquí es lo que ya sabemos y del mismo modo en negativo, que rotará en la otra dirección. ¿Qué ocurre? Que si yo llego a este punto, que estoy haciendo esta rotación de la nave y le digo, voy a crear otra variable, un float, que coja la rotación actual de esta nave, que básicamente es de este objeto, la nave, voy a coger el valor del eje Z, que es el que estamos cambiando y el que nos interesa,
00:12:42
en su valor de ángulo
00:13:12
seuler, ¿vale? y justo a continuación
00:13:15
¿vale? esto de momento lo omitimos
00:13:17
pero justo a continuación vamos a ver
00:13:19
el valor que está mostrando esto
00:13:21
y vais a ver que no es concordante siempre
00:13:23
bueno, voy a comentar de hecho
00:13:25
esto que tenemos aquí
00:13:27
vale
00:13:28
vale, tenemos estas líneas
00:13:30
en principio está bien, guardo y vamos a ver
00:13:33
que yo cuando
00:13:35
vamos mostrando ese eje Z
00:13:37
simplemente en la consola
00:13:39
¿vale?
00:13:41
a ver que esto se quite, yo empiezo a dar aquí y veis que si yo pongo aquí la nave prefab, aquí pone z menos 61 y sin embargo si vemos la consola pone 298 y vais a ver que este valor siempre está entre el 0 y el 360 mostrando una rotación de una sola vuelta,
00:13:42
Y yo sigo haciendo esta rotación, veis que nunca es negativo el valor y aquí sí estamos viendo negativos. ¿Qué significa? Que aunque en el inspector no lo muestre con valores negativos, realmente en el código y como está funcionando por debajo esto de los ángulos Euler es siempre en un valor que muestra entre el 0 y el 360 en positivo.
00:14:06
Esto implica muchas dificultades porque si por ejemplo yo quiero decirle que esta nave me la mueva al menos 4, realmente por detrás lo que está gestionando es un 356, que son los 360 menos los 4.
00:14:27
Entonces, si yo quiero girar la nave con algo que sea directamente usar los ángulos Euler, manipulando estos valores directamente, hay que hacer operaciones intermedias o conversiones para que esto no dé problema.
00:14:46
Porque si ponemos valores negativos, lo que va a hacer es saltar directamente al final del recorrido del siguiente, ¿vale? Porque pasará de 0 a 300 y pico, yo que sé, y va a haber saltos y va a haber problemas y para limitar también pueden surgir ciertos inconvenientes, ¿vale?
00:15:02
Por eso os doy aquí un planteamiento, hay más, etcétera, que quiero comentar para que veáis también el uso que se puede dar a este operador módulo del que hablamos el otro día.
00:15:20
Entonces, esta línea ya, por ejemplo, la voy a dejar ahí que en todo momento nos enseñe el valor del angular Euler de z según estamos haciendo esta rotación,
00:15:32
Pero lo que vamos a hacer es esta operación, que de primeras puede costar, pero es esta variable de current rotation, que en su momento valía este valor, siempre positivo, hemos dicho, de 0 a 360. Voy a hacer que se guarde y opero, que esto se puede hacer también.
00:15:43
Y es algo que vimos cuando se usaba la suma, por ejemplo, que se podía hacer este current rotation es igual a current rotation más 1, ¿vale?
00:16:01
Recordad que se puede operar, esto es un ejemplo, se puede guardar en una variable un valor que apele a esa variable y luego más operaciones aritméticas, ¿vale?
00:16:11
Que digo que a veces parece un poco intuitivo decir current rotation es igual a current rotation extrajosa, ¿vale?
00:16:21
Lo que está haciéndose aquí es guardar un contenido que estamos designando aquí y estamos apelando en este momento, en el que todavía no se ha guardado, está en esa operación, este valor que se había puesto.
00:16:26
Entonces, imaginaos que yo he rotado 4 a la izquierda, ¿vale? Ese menos 4 que se ve en el inspector, pero que a nivel interno el código realmente aquí está viendo reflejado como un 356, ¿vale?
00:16:38
¿Qué es lo que vamos a hacer aquí? Poner siempre que este valor sea mayor a 360, ¿vale? Es decir, si yo tengo una current rotation, bueno, en realidad no es que sea siempre mayor que 360, es que esté en un rango, ¿vale?
00:16:52
Que se mueva entre 180 y menos 180.
00:17:13
¿Qué conseguimos aquí?
00:17:16
Que este valor que tengamos aquí, al dividirlo entre 360 y dar el módulo, ¿vale?
00:17:17
Básicamente estoy diciendo qué grados hay, ¿vale?
00:17:24
En una sola vuelta.
00:17:27
¿Por qué?
00:17:28
Porque si, por ejemplo, habíamos hecho que en este valor fuera en vez de menos 4, menos 364, ¿vale?
00:17:29
Como hemos dicho que los ángulos Euler solo operan en un giro, es decir,
00:17:37
de 0 a 360 y no pasa de ahí, pues al hacer este módulo estamos diciendo, oye, al dividirlo entre 360, ¿cuántas vueltas hemos dado?
00:17:42
Entonces se le suma a ese ángulo estos 180, se divide ese valor entre las vueltas que puede tener y luego esa compensación,
00:17:51
es decir, esos 180 que se habían contado, al final el resultado de esto puede ser 0, 1, 2, que es el número de vueltas,
00:18:00
que es lo que estamos consiguiendo con esta operación. Si es positivo, se estabiliza con esto para que llegue a cero.
00:18:08
Si, por ejemplo, hemos girado 180 y al girar 180 le sumamos 180 y lo llevemos entre 360, el módulo va a ser cero
00:18:15
y al restarle este 180 se va a quedar en el valor negativo. Con esta operación lo que estamos haciendo en todo momento
00:18:24
es compensar el número de vueltas que hay y también restringir que los valores que dé esto sea entre menos 180 y 180, porque si tiene el valor máximo, que va a ser 0, va a dar menos 180, y si está entre 159, cuando se le resta 180, pues va a estar en los valores positivos, del comienzo del giro, digamos.
00:18:31
Básicamente, si yo me meto ahora en el código, y esto me sirve sobre todo para hablaros de estas discordancias que hay entre el eje Z y lo que va mostrando la consola.
00:18:59
Vais a ver que está todo el rato, a ver, aquí lo voy dando, va a estar en todo momento yendo entre los valores de 180 positivos y luego automáticamente pasa a menos 180.
00:19:11
Y una vez tenemos esto preparado, lo que podemos ir haciendo y haberlo convertido ya a una rotación que va entre menos 180 y más 180, que no es lo que hace por defecto los Euler angles, sí que podemos crear otras variables y poner unos límites nosotros, que es menos 90 como máximo de giro hacia la izquierda y más 90 de máximo de giro a la derecha.
00:19:23
Y con esta conversión hecha entre 180 y menos 180, es decir, si esta rotación es menor al mínimo o mayor, recordad que este operador de las dos líneas es una condición o la otra, o mayor a estos 90 grados, es decir, dicho de otra manera, si sale dentro de los rangos que queremos definir aquí,
00:19:46
Y lo que vamos a hacer es decir que esta rotación, este valor que puede estar por encima de 90 o de menos 90, si está en alguna de esas dos situaciones que se sale del rango que queremos, vamos a limitarlo y vamos a hacer que este giro se encuentre dentro de unos límites.
00:20:08
Para ello, este método no está en los contenidos. Esto es de ampliación lo que os estoy contando todo. Hay una operación, un método que se llama el MathF, que es una clase que hay en Unity para operaciones matemáticas.
00:20:31
Y este clamp, que significa o sirve o se usa en Unity, nos metemos, dice, vale, existe esta clase que si nos fijamos con esto se puede dar el valor que tengamos o que queramos evaluar y queremos que lo que devuelva este método sea siempre o esté limitado a un número mínimo o a un número máximo.
00:20:51
Es decir, que aquí ahora mismo, si estamos pasándole una rotación de 0 o de 10 o de 50 o de menos 50, como está dentro de los mínimos y máximos que estamos marcando en los otros dos argumentos, pues no lo va a cambiar.
00:21:16
Pero si este valor de pronto valiera 180 o 150, porque se sale del máximo que hemos marcado, lo pondrá en el máximo. Es decir, lo restringirá ese máximo. Lo dejará que como máximo de aquí salga un valor de 90 y como mínimo uno de menos 90. Y lo guarda en current rotation de nuevo.
00:21:33
Y ya por último, lo que decimos es, este valor de Euler-Engels directamente lo modificamos, es decir, estamos como tocando el transform, estos valores que tenemos aquí, para que el X y el Y de esa rotación se mantengan estables, no las estamos afectando.
00:21:55
Esto lo expliqué el otro día, que si ponemos el nombre del eje, pues se mantiene, no está habiendo ninguna perturbación de ella, y coja este valor, que va a estar siempre entre máximo 90 o menos 90, y lo ponga en el Euler-Angels.
00:22:15
Entonces, básicamente estamos haciendo este rotate como veníamos haciendo y con todo esto lo que hemos hecho es, por un lado, recoger el eje Z, hacer con esta operación que se mantenga entre el menos 180 y el 180,
00:22:29
Porque lo que hace es dar unos valores que al darse entre 0 y 360 se estabilizan restándole 180, ¿vale? Y si es un 0 se queda en el menos 180 y si al dar un máximo de grados posibles de 360 al resultado de esto antes de su operación, antes de restarle 180, si el máximo es 360 al restarle 180 se queda en 180 y si es 0, ¿vale?
00:22:45
Es decir, ha comenzado una rotación nueva, un ciclo de rotación, al restarle menos 180 se queda en el mínimo de 180.
00:23:13
Entonces, digamos que el rango de esos 360 grados, en vez de ir de 0 a 360, con esto hemos conseguido que se quede en un rango de menos 180 a 180,
00:23:19
que es lo que nos interesa para operar a nosotros con valores negativos, que es lo que nosotros vemos en ese transform.
00:23:29
Aquí fijamos esta rotación máxima o mínima, que es la que hemos establecido.
00:23:36
Ya os digo, si quisiera que fuera menos 120 y 120, con esto, siempre y cuando esté dentro de este rango, porque si no ya estamos volviendo a salirnos de rango, podemos marcar una rotación máxima y mínima.
00:23:39
Y con esto, al final lo que decimos, esta rotación que hemos dado, al final que se traduzca y que se ponga en el transform dentro de este rango que se ha puesto aquí limitado por este clamp.
00:23:55
Esta sería un poco la lógica. Esto se puede hacer de más formas, evidentemente, hay muchas.
00:24:09
Pero bueno, esta es una que me sirve para explicar también esto del módulo y veis, ahora el máximo es 120, a ver, 120, 120, esperad que aquí voy a quitar, igual lo está volviendo un poco loquer, que es, vale, yo giro y se queda en 120, vale, sobrepasa un poco los 90 y 120, vale.
00:24:13
Entonces ahora, es verdad que esta rotación es un poco rara porque se queda como mirando para abajo, voy a poner 45-45 y con esto ya tengo una rotación preparada para tener límites, ¿vale? Y en principio más o menos debería funcionar en cualquier, ¿vale? Más 45 menos 45, se queda ahí en un grado intermedio.
00:24:38
Y ahí sí que, además, al ser un rotate, sí que tiene ese suavizado independientemente de que aquí tenga un input que tarde más o menos en captarse, ¿vale?
00:25:01
Que, ojo, si vamos a hacer esta, yo lo llamo interpolación, esta suavidad, mejor dicho, ¿vale?
00:25:11
Y queremos que sea todo en base al código, aquí lo más correcto sería nuevamente poner un valor muy alto, ¿vale?
00:25:18
Porque no queremos que tarde en recoger el valor del input.
00:25:24
Queremos que vuelva a ser, como viene por defecto, por ejemplo, este 1000 y 1000, ¿vale?
00:25:27
Y, bueno, pues ahora la rotación empieza y se hace con el rotate, básicamente, ¿vale?
00:25:31
No sería ninguna tontería poner un time, delta time, ¿vale?
00:25:39
Para hacer esta estabilización que hablamos de la rotación, de los tiempos de ejecución de la date, ¿vale?
00:25:44
A lo largo del tiempo.
00:25:51
Entonces, una cosa es esta estabilización que se hace en el momento de la rotación con que luego estemos en todo momento recuperando un valor de los Euler angles, que es básicamente leer, en este caso cuando lo estamos recogiendo, leer lo que pone en el componente transform del objeto.
00:25:52
Y si estás aplicando estos Euler angles, básicamente lo que estás haciendo es pasar una posición, una coordenada que ya tienes.
00:26:12
Por eso en este caso no habría que poner time delta time, porque ya está dando valores automáticamente.
00:26:26
Tendrás que estabilizar en todo caso lo que da ese valor para que llegue a los Euler angles.
00:26:33
una duda ya que mañana no podría asistir a tutoría bueno tenía el mismo problema y básicamente tiene
00:26:40
un problema en la unidad 2 en la tarea que es que tiene un elemento que está instanciando los
00:26:50
obstáculos no recordemos que básicamente en esta tarea tenemos esta nave que se va moviendo etcétera
00:26:56
y bueno poder rotar etcétera ahora vemos algunas posibilidades pero que llega un momento que no se
00:27:04
siguen instanciando estos obstáculos, ¿vale? Ella indica que tiene, igual que yo, de otra forma, pero ha llegado a la solución correcta,
00:27:12
tiene un código que sirve para instanciar, igual que hacíamos en la primera tarea, que sirve para instanciar un obstáculo que está capturando
00:27:20
por este serialized field como un GameObject, ¿vale? Igual que hacíamos en la primera tarea, y lo tiene ahí.
00:27:31
¿Qué problema está teniendo?
00:27:36
¿Vale?
00:27:39
Es importante, porque es verdad que esto se olvida a veces rápido,
00:27:39
pero es que ella ha puesto que el GameObject, que es instancia,
00:27:43
que está juntando aquí, no es el prefab en sí, ¿vale?
00:27:47
No es este prefab que tenemos en el área de proyecto,
00:27:50
sino que lo que ha incorporado es que ella metió un obstáculo ya
00:27:54
para tenerlo aquí de referencia, imagino, ¿vale?
00:27:57
Y dijo, este es el obstáculo, a ver, este es el obstáculo,
00:27:59
me pongo en instanciador
00:28:03
y este es el obstáculo que lo ha arrastrado
00:28:05
y parece el mismo, pero que hay problema
00:28:07
hay, que ella en cierto momento
00:28:10
con todos los obstáculos, dentro del script del obstáculo
00:28:11
si me meto en el obstáculo
00:28:14
se está moviendo y también se destruye
00:28:15
a sí mismo, que es lo que se pide
00:28:17
con la función destroy
00:28:19
que pasa, que como el instanciador
00:28:21
está cogiendo este
00:28:23
obstáculo de la jerarquía
00:28:25
si yo doy play al juego
00:28:27
vais a ver que se están
00:28:29
que se están reproduciendo
00:28:31
los obstáculos y en cuanto se destruye
00:28:35
ahora está ya otro, aquí no aparece
00:28:36
es decir, se ha perdido porque
00:28:39
se ha borrado ese obstáculo que teníamos en la jerarquía
00:28:40
que es este que está
00:28:43
cogiendo como referencia y cuando
00:28:44
se destruye, porque es cuando pasa
00:28:46
la cámara, donde lo he configurado se ha destruido
00:28:49
solo ha dado tiempo a hacer un clon
00:28:50
una instancia y aquí de pronto aparece
00:28:52
este mensaje de missing y ya no sabe
00:28:55
que seguir instanciando y ya no hay copias
00:28:56
¿vale? es la diferencia con
00:28:59
Si yo borro y a este instanciador le digo que sea este obstáculo, que al estar fuera de la jerarquía, está como en un nivel superior porque está en el proyecto, pues yo si arrastro este, este nunca se va a borrar. Fijaos que yo me estoy fijando aquí en obstáculo, no está en ningún lado, pero se están haciendo estas copias.
00:29:00
el tiempo con la corrutina
00:29:18
como está pedido en la tarea
00:29:21
pero este obstáculo aquí no se borra
00:29:23
por tanto siempre el instanciador
00:29:26
va a tener la referencia de qué objeto
00:29:27
instanciar
00:29:29
¿qué tal esto? entiendo que lo que es la
00:29:30
instanciación más o menos la entendéis
00:29:33
con este detalle de que os puede
00:29:35
interesar en muchas ocasiones
00:29:37
que el
00:29:39
elemento que estemos llevando
00:29:40
o recogiendo en una variable de tipo GameObject
00:29:43
no sea un prefab de la jerarquía
00:29:45
sino que normalmente nos va a interesar más que sea el prefab del proyecto en sí, ajeno a que se borre o no de una jerarquía uno de estos dos elementos.
00:29:47
De hecho hay otro método del que se ha hablado un poco por encima que es, y pensarlo, ahora mismo no tengo un ejemplo, me ha venido así de pronto,
00:30:04
Pero tened en cuenta que a lo mejor en un start, ¿vale? Instanciáis o recogéis un elemento que todavía no se ha creado en la jerarquía, ¿vale? Y todavía no está aquí y bueno, pues un poco dicho lo mismo, si yo la opción que dijera es este es el obstáculo que voy a instanciar, ¿vale? Lo que estábamos hablando antes, lo voy a cambiar el nombre para que sea más notorio el cambio entre uno y otro, lo voy a llamar en español obstáculo, ¿vale?
00:30:11
Y el que estoy incorporando al instanciador es obstáculo, ¿vale? Si yo este elemento a lo mejor lo genero en algún momento que es en el start, ¿vale? Y en ocasiones puede suceder que tengo aquí un, digamos que estoy incorporando un elemento a un serialized field, ¿vale?
00:30:38
En ocasiones, en vez de coger ese elemento, cargar ese GameObject, esa variable, en el momento de start, existe otro método que se ejecuta y está preparado antes de que se lance el script, que es este Awake.
00:31:00
Esto lo dejo ahí un poco planteado
00:31:14
Pero si en alguna ocasión os encontráis en la circunstancia
00:31:17
De que aquí queréis rellenar por código
00:31:22
Un GameObject que todavía no se ha generado
00:31:24
En la jerarquía
00:31:27
En ocasiones se puede cargar previamente con esta Wake
00:31:30
Veis que eso, que cuando la cámara para
00:31:34
Desde que para hasta que se coloca la cámara
00:31:42
Hay un pequeño tirón
00:31:45
Es algo que se pedía o que es recomendable.
00:31:46
Entonces, en esa cámara, para que lo veáis, tengo un script llamado cameraFollow,
00:31:51
como se puede llamar seguimiento cámara, ya sabemos que eso es una convención que usemos nosotros.
00:31:56
Y vais a ver que lo que estoy buscando, las dos variables públicas o serializadas,
00:32:02
que las tenemos aquí, básicamente, tenemos por un lado, y son estas dos,
00:32:07
Una que tiene el objetivo al que tiene que estar siguiendo
00:32:15
Que tenemos mejor dicho de referencia
00:32:19
Para que la cámara lo haga en relación a ese objeto
00:32:22
Básicamente lo que estamos haciendo
00:32:25
Si lo decimos incluso verbalmente es
00:32:27
La cámara se va a mover X en relación a la nave
00:32:29
Entonces siempre hay que tener esa relación a la nave
00:32:34
Aquí en vez de tener el GameObject
00:32:36
Lo que cojo son, que esto lo vimos también en la primera tarea
00:32:38
Os hablo de ello
00:32:42
la variable transform para recoger
00:32:43
los valores de este
00:32:45
componente, lo guarda
00:32:47
y yo lo que le he dicho a la nave es
00:32:48
oye, tú sigue a esta nave prefab
00:32:50
es la referencia
00:32:52
y vais a ver que lo que hago es
00:32:54
en el primer momento, según arranca el juego
00:32:56
es la posición actual
00:32:58
esto que se llama current post
00:33:00
la posición actual
00:33:02
en la que debería estar la nave
00:33:04
la cámara, perdonad, este objeto que tiene
00:33:06
el script
00:33:08
que coja
00:33:10
la posición
00:33:12
de origen que tengo yo aquí
00:33:13
¿vale? ¿por qué? porque si yo
00:33:16
y esto además, si no da
00:33:18
tirones, si yo pongo aquí
00:33:20
la cámara, vais a ver que cuando le doy al play
00:33:22
da ese tirón
00:33:24
y se coloca, ¿vale? esto da este
00:33:26
efecto de que se va moviendo hacia ese punto, pero
00:33:28
básicamente, yo voy a estar en todo
00:33:30
momento partiendo de una posición
00:33:32
que marco y que deberíamos poner aquí
00:33:34
como centrada
00:33:36
para que coja esa de comienzo, y luego en el
00:33:37
update, voy a estar diciendo, creo una variable que está aquí,
00:33:40
de un vector 3, dado que hablamos ya de posiciones,
00:33:44
rotaciones, escala, que se basan en tres valores, voy a crear
00:33:48
un valor que se llama targetPos, que de momento simplemente
00:33:52
guarda este vector, que va a coger la posición en los tres
00:33:57
ejes de donde está la nave. Por eso pongo target y no es el
00:34:02
Transform, a diferencia de aquí, si os fijáis, pongo coge la posición de esta nave en X, ¿vale? En X, básicamente, no quiero que haya un offset, no quiero que haya un offset lateral con respecto a la nave, quiero que haya un offset hacia arriba, ¿vale? Y en profundidad hacia atrás, ¿no? Para que esté alejado hacia atrás y hacia arriba, porque básicamente, pues es eso, me quiero alejar hacia atrás y subirla un poco para angularlo hacia abajo.
00:34:08
¿Qué hago y qué se puede hacer? Crear una variable, igual que se podría poner aquí un número a pelo, pero mejor si lo agrupamos en una variable, que uno indique cuánto va a ser ese offset en el eje Z y cuánto va a ser el offset en el eje Y.
00:34:33
vale y le digo vale el offset en el eje y va a ser pues que va a coger la
00:34:46
posición de la nave y si está en 10 pues se va a poner la cámara en 25 más arriba
00:34:51
y del z vale pues si la nave está en cero pues se va a ir hacia atrás va a ir
00:34:56
hacia menos 6 porque lo que puesto aquí con esto al ir cambiando estos números
00:35:02
el offset va a ser mayor o menor aquí todavía no lo estamos aplicando vale lo
00:35:06
tengo guardado y aquí me está dando la posición donde debería estar la cámara
00:35:12
en relación al target que es la nave y luego le digo ya sí efectivamente ojo
00:35:17
quiero que la nave esté se podría hacer directamente se podría decir oye quiero
00:35:22
que la nave esté en
00:35:28
quiero que esté en target post pero voy a hacer otra cosa
00:35:33
Que si no, veo que la lío, que se me olvida.
00:35:39
Voy a hacer que esto es buena práctica.
00:35:41
Digo, aquí tengo algo seguro que me funcionaba.
00:35:43
Lo comento y ahora digo, quiero que esté en target post.
00:35:45
Target punto post.
00:35:49
No, no, yo quiero post.
00:35:53
Y quiero que en todo momento la posición de este objeto, ¿vale?
00:35:56
Cuando ponemos transform y posición nos hablamos de lo...
00:36:00
Perdona que a veces sea redundante, ¿vale?
00:36:03
Pero es un poco para ir repitiendo y que vaya sentándose cosas.
00:36:04
Quiero que la posición de este objeto sea la del target post, que es básicamente la que hemos guardado aquí con ya los offsets aplicados.
00:36:09
Si yo es esto lo que aplico a esta cámara, pues vamos a ver que no va a haber este retardo.
00:36:17
Simplemente la cámara va a tener ese offset y se va a mover con la cámara, como si estuviera anclada en este caso a la nave a cierta distancia y se moviera con la nave.
00:36:23
Vale, pues ya está.
00:36:32
Si yo el offset le digo que en vez de Z sea, bueno, antes se lo he dicho al revés, que era Z y tal
00:36:32
Bueno, si le digo que en vez de a 15 unidades por detrás, esté a 50, simplemente con cambiar ese valor
00:36:39
Vais a ver que va a estar anclada igual, pero bastante más lejos
00:36:45
Ya hablamos que existe, ¿vale? Y esto en la instanciación lo hablamos a colación de que también se creaba, se podía crear una variable de tipo transform
00:36:50
Y fijaos que aquí se refiere a la clase transform con la T mayúscula, ¿vale? Normalmente, y lo vais a ver en el tema 3, cuando queremos hacer cambios en un componente, es decir, recordad que los componentes son estos distintos bloques que proporcionan propiedades a los GameObjects, ¿no?
00:36:59
hay uno que se llama Transform que está siempre
00:37:21
en todos los GameObjects
00:37:23
a excepción de algunos de
00:37:25
la UserInterface, bueno, algunos
00:37:26
puntuales que no lo tienen, pero en general
00:37:29
todos tienen este Transform porque todos se ubican en el espacio
00:37:31
y tienen una rotación y una escala, ¿vale?
00:37:33
impepinablemente, entonces
00:37:35
a diferencia de por ejemplo lo que tendremos que hacer
00:37:36
en la siguiente tarea cuando queramos
00:37:39
cambiar, por ejemplo
00:37:41
estoy poniendo uno de los valores
00:37:43
una de las propiedades
00:37:45
del componente RigidBody que no se va a poder
00:37:46
poner directamente RigidBody.más para cambiarlo, a diferencia de eso, en Transform se considera que al ser tan universal, se puede apelar a él directamente sin tener que recogerlo.
00:37:49
Esto cuando veáis la unidad 2, vais a ver eso, que por ejemplo, si yo quiero cambiar, vamos a hacer el ejemplo de hecho, una de las propiedades de un RigidBody es la masa,
00:38:05
¿Vale? El más. Y lo podemos querer cambiar. Y yo digo, voy a crear un RigidBody, lo llamo RB, ahora os explico esto un poco más en detalle.
00:38:13
Aunque ya os digo que esto se explica en la unidad 3. Pero si yo capturo este RigidBody, lo escribo y ahora lo voy explicando, que va a ser más sencillo.
00:38:25
Y yo, uy va, aquí me ha hecho lo que ha querido, digo quiero meterme en la masa y decirle que esto es igual a 10, ¿vale?
00:38:35
Básicamente con este código lo que estoy diciéndole es, este objeto que tiene este script incluido, que es la cámara, ¿vale?
00:38:45
Al final un script se incorpora en un GameObject como un componente, ¿vale? Si yo este componente, este objeto que tiene esta clase CameraFollow, quiero cambiar sus valores, ¿vale? Al final lo que tengo que hacer es crear una clase que se llame como el componente.
00:38:55
Y vais a ver que para ir accediendo a los distintos componentes, básicamente va a haber que hacer una variable de ese tipo de componente.
00:39:19
Por ejemplo, si yo quiero variar los valores de cámara, aquí habrá una clase que se llama cámara.
00:39:29
Si quiero variar los de audio listener, va a haber una clase que se llama audio listener.
00:39:35
Y esta creación de clases, clase manipulador, audio listener. Tendremos que ir, para poder apelar a qué estamos haciendo los cambios, va a haber siempre que crear una variable con el tipo de variable llamada como el componente.
00:39:42
A veces pueden cambiar un poco los nombres, pero fijáis que, no me lo sé de memoria, sé que como hay uno que se llama AudioListener, yo lo pongo ahí y es un tipo de clase posible, ¿vale? Que se puede crear como variable. Y ya a partir de aquí lo usaremos con el nombre que hayamos atribuido a esa variable, ¿vale?
00:40:03
Entonces, ¿qué ocurre? Que hay un proceso intermedio, que es que aunque pongamos que aquí vamos a trabajar con una variable de tipo RigidBody, hasta que no le digamos a qué RigidBody se refiere, que es lo que se hace con esta operación, ahora la explicamos en más detalle, no va a poder hacer ningún cambio.
00:40:17
Fijaos, ¿vale? Bueno, primero, para que veáis que esto ocurre, si como yo le he dicho que la masa me la cambia a 10, yo cuando guardo y ejecuto este código, ¿vale?
00:40:39
Vais a ver que efectivamente está cambiando la masa a 10. ¿Veis que se ha puesto 10 al lanzarse? ¿Vale? Que sí que está habiendo este cambio mediante código.
00:40:50
¿Qué pasa si yo borro esta línea?
00:40:59
Aparentemente no pasa nada, pero vais a ver que solo por borrar esa línea que ahora explicábamos,
00:41:03
yo le doy a play y este cambio no se realiza, no se pone a 10.
00:41:10
Y dices, pero según la lógica, yo estoy diciendo que la variable RB se opere con los contenidos de este componente RigidBody
00:41:14
y me cambie el parámetro, RB, pues dentro tiene propiedades, que es el de masa, que me lo cambia a 10.
00:41:25
¿Por qué no está haciendo esto? Porque hay que usar la captura de componentes.
00:41:33
La captura de componentes básicamente es un paso, a veces un poco tedioso, que es igual que cuando decimos que esto es un transform
00:41:39
y ponemos un serialize field y hasta que no arrastramos en el inspector cuál es ese elemento,
00:41:45
no sabe a qué elemento tiene que influir
00:41:53
o cuál tiene que guardar aquí
00:41:55
voy a hacer el ejemplo de decir
00:41:56
serializeFill y esto lo pongo como un serializeFill
00:42:00
y tengo aquí ese serializeFill
00:42:03
y como lo he generado como un serializeFill
00:42:07
cuando yo voy
00:42:09
a esta cámara
00:42:11
vais a ver que se ha generado
00:42:12
un serializeFill de esta variable
00:42:15
llamada RB que está pidiendo
00:42:17
ahora está vacío, está pidiendo
00:42:19
que le incorporemos un RigidBody
00:42:21
¿qué quiere decir esto por defecto?
00:42:22
que hasta que no arrastremos aquí
00:42:26
un GameObject con
00:42:27
RigidBody, como por ejemplo este mismo
00:42:29
si yo arrastro MainCamera, tiene un RigidBody
00:42:32
entonces me coge el RigidBody de MainCamera
00:42:34
y sabe que tiene que cambiar
00:42:36
RB tiene que cambiar este RigidBody
00:42:38
y no otro
00:42:40
pero hasta que no lo captura
00:42:41
o no se lo determinaba de una forma explícita
00:42:43
esto está vacío
00:42:46
simplemente ha creado una variable
00:42:47
que es de tipo RigidBody
00:42:49
Y esto también lo comenté al principio, pero la gracia que tiene que haya distintas clases con los nombres de los componentes es que aquí si nos metemos, ¿vale? Ya os dije que si dais a la tecla control sobre el nombre de las variables, o mejor dicho, de las clases, ¿vale?
00:42:51
Lo que nos metemos es en un código que ya alguien ha hecho en Unity o no sé quién desarrolla esto, sinceramente, con todo lo que se ocupa ese componente, ¿vale? Por eso ya aparecen estas variables, estos campos serializados, por eso básicamente un componente tiene unas propiedades y no otras, ¿vale? Y unos comportamientos y no otros, ¿vale?
00:43:09
Entonces, recordad que básicamente tenemos preparado que queremos afectar a un componente, y por eso ponemos su nombre, pero hasta que no le digamos qué componente de los que hay en la escena es, básicamente Unity no sabe con cuál tiene que hacer nada.
00:43:31
a ver
00:43:45
ahí estamos
00:43:48
otra vez, ¿vale? entonces
00:43:51
¿cómo se hace esto? se puede hacer
00:43:52
o mediante un serialize fill y decírselo
00:43:55
a través del editor, que es lo que hemos hecho
00:43:57
con este target, ¿vale?
00:43:59
o podemos hacerlo por código
00:44:01
lo que hay que hacer es, una vez se ha creado esta caja
00:44:02
recordad esta variable, que a partir de ahora
00:44:05
aunque sea de tipo rigibody
00:44:07
su nombre que le hemos puesto es
00:44:08
rb, como podríamos poner
00:44:11
joaquín, yo que sé, cualquiera
00:44:13
Yo puedo decirle, vale, rb, esta variable, esta caja, lo que tiene que usar es coger este componente y la sintaxis es la que sigue. Se abren estas llavecitas y paréntesis.
00:44:14
¿Vale? El paréntesis aquí, por defecto, en los usos que vamos a dar nosotros, sirve, y recordad que cuando estamos llamando, esto lo hacíamos, por ejemplo, en el que hemos visto antes de mover el objeto, ¿vale?
00:44:27
Para que se sepa que un método al que estamos llamando es un método y no otra cosa, hay que poner esos paréntesis, ¿vale?
00:44:46
Si no, no es un método, ¿vale? Siempre que veáis unos paréntesis llenos o vacíos después de un nombre, suele ser porque es un método al que estamos apelando.
00:44:53
Entonces, GetComponent es un método, ¿vale? Pero funciona de una forma diferente a otras ocasiones, que es que en estas llaves es donde ponemos el nombre del componente, ¿vale?
00:45:03
con esta línea lo que estamos
00:45:11
haciendo es que esta caja que abrimos aquí
00:45:13
de tipo RigidBody, porque vamos a usar
00:45:15
las propiedades que
00:45:17
se han ya programado previamente
00:45:19
de ese componente
00:45:21
llamado RigidBody, es decirle, vale
00:45:23
yo quiero que guardes en esa caja
00:45:25
el componente RigidBody
00:45:27
de este objeto que tiene el script
00:45:29
es decir, ahora mismo en RB
00:45:31
como este es el script
00:45:33
que tiene este código
00:45:35
al lanzarse en el start
00:45:37
dice, vale, me meto y le digo, a ver, bueno, esto ya lo puedo cerrar, me meto y dice, a ver, me meto y cojo el componente que hay en este objeto,
00:45:39
porque no le estoy diciendo que sea en otro, RigidBody, vale, y lo meto, me ha dicho en, este ya también me lo voy a mover,
00:45:49
y me ha dicho que lo meta en RB, ¿vale? Y a partir de ahora RB sí que se va a estar refiriendo en todo caso a ese componente que está en este objeto, ¿vale?
00:45:58
Y por eso, a partir de ahí, sí podemos entrar en las propiedades. Yo ahora pongo RB y al dar a punto, ¿vale? Y ver las propiedades, vais a ver que hay muchas propiedades, pero básicamente es Kinematic, quedad con estos nombres, es Kinematic, más, si voy arriba estará Drag, por ejemplo, Angular Drag, Drag, ¿vale?
00:46:07
Todo esto son propiedades que, si os fijáis, lo que hacen es alterar el contenido de este componente, ¿vale? Es la forma de acceder. Si yo aquí pongo drag y le digo que drag es igual a 10, nuevamente, ¿vale? Cuando guardo, estoy diciendo, vale, capturo en una variable de tipo rigidbody, mediante esta operación, este rigidbody, ya puedo acceder directamente a las propiedades de este rigidbody, entre una de ellas es drag, ¿vale?
00:46:28
Al darle a reproducir vais a ver que drag se pone a 10.
00:46:56
Esta es la forma de acceder por código a las propiedades de cada componente.
00:47:00
Vuelvo rápidamente y luego volvemos a esto.
00:47:06
¿Qué sucede con el transform?
00:47:09
Que si esto hubiera que hacerlo con el transform para cambiar la posición, para acceder a position, sería un rollo, por decirlo así rápido.
00:47:11
Habría que hacer transform, darle el target o el nombre que fuera, luego target, luego igual a get component, transform, ¿vale? Y esto sería para preparar que target funcionara como transform y ya pudiera entrar a position o a lo que fuera.
00:47:19
¿Qué han hecho? Se ha simplificado porque transform se usa tanto que sin necesidad de hacer nada de todo esto que hemos hecho para, por ejemplo, rb o acceder a cualquier otro. Y esto es cualquier otro de los componentes en los que queramos cambiar parámetros o propiedades, pues directamente al dar a transform ya se ha hecho toda esa operación.
00:47:35
es un atajo, digamos, a este componente transform, ¿vale?
00:47:56
Lo veis, transform es la clase donde está todo el código,
00:48:00
pero hay un atajo que es, con este transform ya,
00:48:03
que apela directamente a todo este recorrido que hemos hecho.
00:48:05
Y por eso ya podemos acceder al position, al Euler angles,
00:48:08
a la escala local, ¿vale?
00:48:12
Por eso es esa diferencia entre transform
00:48:16
o otros tipos de componentes, ¿vale?
00:48:18
¿Qué pasa? Que cuando damos a transform,
00:48:23
básicamente en una línea estamos diciendo que está refiriéndose al transform de ese objeto, no de otro, de ese objeto.
00:48:25
Por eso, a diferencia de cuando usamos el transform capturado por un serialize field llamado target,
00:48:32
aquí al decirle target.position, no estamos accediendo a las propiedades del transform de ese objeto,
00:48:38
estamos accediendo a las propiedades de transform de ese objeto al que hemos referenciado aquí.
00:48:43
Y por eso ese target.position no se refiere a la posición del mismo objeto que tiene el script,
00:48:49
sino a la posición, ahí está accediendo al transform de este objeto, aquí.
00:48:54
Esto también lo expliqué, pero creo que no es de más.
00:49:04
Cuando creamos un objeto vacío, ves que ya viene con el transform, ¿vale?
00:49:09
Otra pista de que el transform es tan universal que ya se hacen atajos para acceder a él.
00:49:12
Pero que al final lo que proporciona que un objeto sea de una forma u otra
00:49:18
es los diferentes componentes que vamos incorporando.
00:49:21
esos bloques de código que ya están prehechos con sus configuraciones, comportamientos, etc.
00:49:24
Entonces, básicamente, todo lo que vamos a ir haciendo es ir cambiando los distintos componentes de cada objeto.
00:49:29
Si queremos cambiar los valores de un componente, como acabamos de decir,
00:49:37
habrá que hacer ese tipo de variable con el nombre del componente y guardarlo en una variable.
00:49:44
Y ojo, porque también os he dicho que los scripts, a su modo, también son componentes.
00:49:48
Ya os he dicho, esto al final, aunque es un script, se llama CameraFollow y es un componente, lo hemos incorporado como cualquier otro componente.
00:49:54
Por eso hay que arrastrar al GameObject, porque hay que incorporarlo como componente.
00:50:01
A estos scripts se puede hacer desde otros scripts también poniendo su nombre.
00:50:05
Si yo pongo aquí CameraFollow, ¿vale? Veis que esto no existía por defecto, esto se llama así porque hay un componente que he creado yo, en este caso, que se llama CameraFollow y por eso sale aquí.
00:50:10
Si yo desde otro código, y este ya os digo que es el que tiene el código, pero si yo me meto en otro de los scripts que estoy usando, a ver, aquí tengo scripts, pues yo que sé, el de instanciar, lo pongo aquí, yo que sé.
00:50:22
Y yo quisiera cambiar algo de ese otro script que he creado yo, yo si me meto y busco camera follow, veis que está aquí.
00:50:38
En parte porque cuando, esto lo hace automáticamente Unity, pero cuando generamos esta clase, que es en el fondo el componente, veréis que es pública por defecto. Entonces, al ser pública, podemos acceder de otros códigos. Si recordáis, el ámbito es público, es general, se puede acceder de otros puntos.
00:50:46
Por eso, si yo ahora quiero acceder a Camera Follow y le digo, vale, este se va a llamar CF, ¿qué problema hay? Que yo, si luego en el Start digo Camera Follow, y he puesto, bueno, habría que hacer alguna variable, pero, a ver, dejadme que me meta.
00:51:03
Espera, que ya no sé dónde tengo cada código.
00:51:28
Aquí, ¿vale?
00:51:31
Lo voy a unir al otro para tenerlo ahí pegahico.
00:51:32
Igual que tengo propiedades, a lo mejor yo quiero acceder al Offset Camera Z de Camera Follow, ¿vale?
00:51:34
Que es una de sus propiedades.
00:51:39
Si doy aquí a, ¿cómo se llama?
00:51:41
Offset Camera, ¿no?
00:51:43
Sí, a Offset Camera.
00:51:45
No sale aquí en primer punto porque no es público, ¿vale?
00:51:48
Para que sea público hay que ponerlo aquí y hay que ponerlo como público.
00:51:52
Si no, se encapsula.
00:51:56
Si yo ahora pongo punto, ¿aparecerá offset cámara? No. ¿Por qué? Porque nuevamente nos falta una operación, que es decir, ¿cuál es este camera follow?
00:51:57
En principio habrá que decirle que CF capture el CameraFollow, con el problema de que si ponemos esto así, va a buscar dentro de sus componentes ese CameraFollow.
00:52:13
Y Camera Follow no está dentro de los componentes del objeto, del GameObject que tiene instanciar obstáculos. Es decir, yo voy al Instanciador que es el que tiene instanciar obstáculos y no tiene ningún componente llamado Camera Follow.
00:52:32
está en
00:52:49
main camera ¿vale? es un poco lo mismo
00:52:50
de antes ¿qué hay que hacer?
00:52:54
pues hay dos formas
00:52:56
o hacer que esto sea un serialize field
00:52:57
¿vale? y le decimos
00:53:00
arrastrando en el editor, esto lo voy a comentar
00:53:03
porque si no igual da fallo
00:53:05
arrastrar cuál es el game object
00:53:06
que si tiene ese camera follow y ya sí que
00:53:09
al poner cf podremos acceder
00:53:11
a sus variables
00:53:13
¿vale? y primero tenemos
00:53:15
que ir ¿vale? instanciador
00:53:17
a ver, tengo que guardar primero
00:53:19
Y ahora en el instanciador veis que está esperando que le digamos, vale, pero ¿este camera follow de dónde sale? Porque ojo, el camera follow es un script que hemos incorporado a main camera, pero podemos haber arrastrado más objetos, también tiene esa lógica de determinar a qué objeto y qué main camera es el que cambiamos.
00:53:21
Si ahora vamos a instanciador, le decimos, vale, el camera follow del que hablamos es este, el de main camera. Hemos arrastrado main camera y él ya sabe que tiene que buscar el script porque es de tipo camera follow, que realmente es de tipo script. Por eso sale ese iconito de script y no el de prefab, por ejemplo.
00:53:38
Ahora, ¿qué ocurre? Que cuando vamos a este código, al código en el que hemos llamado a Camera Follow, que lo tengo aquí, ahora sí que cuando yo, sin hacer que se componen, porque se lo hemos pasado de forma explícita por el editor, cuando damos a CF, al dar punto, sí que aparecerán, a ver, Offset Camera, Offset Camera Z, Smooth Time, que son las variables o propiedades, ¿vale?
00:53:57
que sí hemos creado en esta clase, en este script.
00:54:25
¿Esto qué significa?
00:54:32
Que de una forma ya que nos permite cambiar
00:54:34
casi cualquier valor de un componente,
00:54:38
si en el start, o lo voy a poner en el update,
00:54:40
en el update, yo qué sé,
00:54:43
si yo ahora le digo, vale, quiero,
00:54:45
yo ahora todo lo que ponga cf me estoy refiriendo a ese componente
00:54:48
cameraFollow al otro script, básicamente
00:54:54
a lo que tengo aquí, ¿vale?
00:54:56
Y le voy a decir que, por ejemplo,
00:54:58
el cameraOffset
00:55:00
en Z, ¿vale? En vez de ponerlo en su
00:55:02
código, voy a decirle es 50.
00:55:04
¿Y ahora qué va a pasar?
00:55:07
Que cuando empezamos el juego, cuando llegue
00:55:08
a este punto, le estamos diciendo
00:55:10
por un código que cambie otro de
00:55:12
nuestros códigos, ni siquiera es uno de los componentes
00:55:14
que ya viene por Unity, sino uno de nuestros códigos
00:55:16
y aunque aquí hubiéramos puesto
00:55:18
el offset de Z a 15,
00:55:20
vais a ver que se va a poner en 50, es decir,
00:55:22
Que igual que hemos hablado antes, se va a poner a 50 de distancia la cámara. Lo ponemos aquí y vais a fijaros, bueno, a ver, que está alejado. A ver, 50, 50, ¿por qué no me está cogiendo el offset?
00:55:24
Y ha puesto aquí unas cuantas cosas. Ah, vale, espera. Si le doy a este offset, vais a ver que aquí el camera offset de pronto se ha puesto en 50. Y no está en el objeto instanciador, que es en el que tenemos ese script, sino en el de main camera. Y aquí se ha puesto el 50.
00:55:41
otra forma
00:56:01
y ya la última
00:56:05
esto que hemos hecho aquí
00:56:06
con un serialize fill
00:56:08
hablar de otro camera follow
00:56:11
si en vez de hacerlo con un serialize fill
00:56:13
lo queremos hacer
00:56:16
por código
00:56:17
el problema que tenemos aquí es
00:56:18
que decimos lo que hemos dicho antes
00:56:21
he preparado que recoja
00:56:23
este script de camera follow
00:56:24
pero en un objeto que no tiene camera follow
00:56:26
entonces al hacer
00:56:28
la captura de componente esta línea es incorrecta porque aquí le estamos diciendo en el script en
00:56:30
este script en el objeto mejor dicho que tiene este script que es instancia los obstáculos y
00:56:38
es instancia dor vale busca o captura el componente llamado camera follow y aquí no
00:56:42
está por tanto esto basta va a dar errores decir no va a ser no de hecho si intento darle a play
00:56:47
vais a ver que lo que ocurre es que da un error porque dice no encuentro la referencia al objeto
00:56:55
que me estás pidiendo que capture vale porque aquí no hay nada que se llame
00:57:00
cámara follow vale en ese caso ya esto es por complicarse a lo mejor lo rápido
00:57:03
aquí nuestro nivel es poner un serie de fil arrastrar y se lo decimos pero aquí
00:57:08
lo que podemos hacer es decirle hay distintos de hecho si nos metemos
00:57:12
esto ya de momento más avanzado y hay uno de los vídeos de álvaro holguera que
00:57:18
si no me equivoco está en la unidad 3 que habla de esto específicamente pero
00:57:22
Hay distintos. Si nos ponemos en la API de Unity Documentation y damos a GetComponent, vais a ver que hay GetComponent a pelo, que es este que estamos usando.
00:57:26
Este de cógeme el componente llamado tal y me lo guardas en una variable de este tipo.
00:57:38
De hecho, veis que suele haber esta rima de que el tipo de variable luego es la que se busca aquí. Se llaman igual.
00:57:42
Aquí lo ha hecho en una sola línea, pero es exactamente lo mismo que hemos hecho la lógica que hemos usado en los ejemplos.
00:57:49
Pero si vais viendo, hay otros que se llaman GetComponentInChildren, GetComponentInParent. Hay otro tipo de métodos, como este Define, si lo buscamos aquí, que es buscar un objeto por distintas tipologías o distintas criterios que demos.
00:57:55
Podemos buscarlo por el tipo de objeto que sea
00:58:17
Por el nombre
00:58:20
Por el index que tenga
00:58:21
Por ejemplo, si vemos este transform
00:58:24
Find
00:58:26
No, mejor dicho, GameObjectFind
00:58:27
Lo que hace será buscar un GameObject
00:58:29
En la jerarquía
00:58:32
Pero por código, ojo
00:58:34
Entonces con esto lo que podemos hacer es poner
00:58:35
Poniendo esta operación
00:58:38
De GameObject.find
00:58:40
Y poniéndole un nombre
00:58:41
Vamos a decirle, oye, búscame
00:58:44
dentro de la jerarquía un objeto que se llame
00:58:46
de tal manera y de ese objeto
00:58:48
ya dentro me buscas el componente
00:58:50
que se llame CameraFollow, ¿vale?
00:58:52
Por ejemplo, nos vamos a quedar que aquí hay un
00:58:54
GameObject que se llama MainCamera que es el que tiene el
00:58:56
CameraFollow. Entonces vamos ahí
00:58:58
y le decimos
00:59:00
¿vale? Quiero que me hagas...
00:59:01
Bueno, borro esto de... Bueno, el GameComponent lo dejo ahí.
00:59:04
Es dentro
00:59:07
de la clase GameObject
00:59:08
que es una genérica que guarda
00:59:10
un montón de código relacionado con
00:59:12
la gestión de los game objects
00:59:14
vale
00:59:16
le decimos find
00:59:17
y vamos a decirle que en vez de por
00:59:19
se puede buscar por las etiquetas que ya lo veremos
00:59:21
por los tipos, hay muchos tipos de búsqueda
00:59:23
pero el básico
00:59:26
si le damos aquí entre paréntesis
00:59:28
el nombre de lo que tiene que buscar
00:59:30
que es main camera hemos dicho
00:59:32
al ser un string hay que meterlo tal cual
00:59:34
lo que va a hacer es
00:59:36
en este punto de código va a buscar
00:59:38
un objeto de la jerarquía llamado main camera
00:59:39
es decir, llegará aquí, al primero que encuentre, se llama así, si hay varios llamados de distinta forma, solo cogería el primero en este caso, y ya una vez encontrado, seguimos enlazando, quiero que de ese objeto que has llegado hasta ahí, me cojas el componente llamado cameraFollow, y ahí sí que está cogiendo el componente de otro objeto, en vez de hacerlo por un serialize fila arrastrando, aquí estamos diciendo busca este objeto y me coges el componente,
00:59:42
Por eso ahora, aunque estemos haciéndolo a través, sin serialize fill, del instanciador, de este script que tenemos en el instanciador, vais a ver que va a cambiar el valor del offset de cámara Z a 50, porque estamos apelando a otro objeto y a otro código.
01:00:11
Entonces yo ahora si ejecuto el juego vais a ver que aquí se ponen 50. Desde el script de un GameObject estamos buscando el componente en otro GameObject y cambiamos una de sus propiedades. Esto es como la base para interconectar distintos scripts.
01:00:28
- Materias:
- Imagen y Sonido
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Primer Curso
- Segundo Curso
- Subido por:
- Daniel M.
- Licencia:
- Todos los derechos reservados
- Visualizaciones:
- 7
- Fecha:
- 14 de noviembre de 2025 - 17:20
- Visibilidad:
- Clave
- Centro:
- IES CIFP a Distancia Ignacio Ellacuría
- Duración:
- 1h′ 00′ 49″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 500.15 MBytes