1 00:00:06,700 --> 00:00:28,359 Bien, hemos visto como un elemento prefab lo hemos cargado en la escena de forma manual, pero eso no es lo ideal o por lo menos no es lo más práctico, porque imaginémonos que voy a tener un NPC con toda su complejidad, sus hijos, su jerarquía, sus scripts asociados y voy a crear 100 NPCs en la escena y además les voy a decir que vayan saliendo de forma aleatoria. 2 00:00:28,359 --> 00:00:30,620 lógicamente eso no lo puedo hacer manualmente 3 00:00:30,620 --> 00:00:33,259 así que tengo que recurrir a código 4 00:00:33,259 --> 00:00:35,060 vamos entonces a aprender 5 00:00:35,060 --> 00:00:36,479 a cómo instanciar 6 00:00:36,479 --> 00:00:38,859 prefabs directamente desde código 7 00:00:38,859 --> 00:00:40,979 y es bastante fácil porque hay una función en Unity 8 00:00:40,979 --> 00:00:42,320 que hace exactamente eso 9 00:00:42,320 --> 00:00:45,179 pero no quiero asociar este script a un GameObject 10 00:00:45,179 --> 00:00:47,039 en concreto porque lo que quiero hacer es crear 11 00:00:47,039 --> 00:00:48,280 prefabs, no quiero 12 00:00:48,280 --> 00:00:50,880 afectar a un GameObject en concreto por eso 13 00:00:50,880 --> 00:00:52,820 y aquí es donde nos viene bien y lo usaremos muy a menudo 14 00:00:52,820 --> 00:00:54,939 como ya he comentado alguna vez, los EntityObjects 15 00:00:54,939 --> 00:00:56,740 los CreateEntity, te voy a llamar 16 00:00:56,740 --> 00:00:59,200 prefab generator, bueno, lo podéis llamar 17 00:00:59,200 --> 00:01:00,939 como queráis, pero esto se me sirve a mí para indicar 18 00:01:00,939 --> 00:01:03,119 que esto no es más que un objeto vacío que sirve 19 00:01:03,119 --> 00:01:05,219 para generar prefabs. Luego le asocio 20 00:01:05,219 --> 00:01:10,260 un script, le he llamado igual que al GameObject 21 00:01:10,260 --> 00:01:11,599 pero vamos, no tiene por qué llamarse igual 22 00:01:11,599 --> 00:01:13,980 y voy a asociar ese script 23 00:01:13,980 --> 00:01:16,159 como un componente de ese objeto vacío 24 00:01:16,159 --> 00:01:18,400 vale, voy a 25 00:01:18,400 --> 00:01:20,079 eliminar la función de update porque no voy 26 00:01:20,079 --> 00:01:21,879 a generar prefabs en cada fotograma 27 00:01:21,879 --> 00:01:24,099 eso sería una locura, para eso veremos las corrutinas en otro vídeo 28 00:01:24,099 --> 00:01:25,760 pero sí que lo voy a hacer al principio, es decir 29 00:01:25,760 --> 00:01:27,500 que cargue cuando empiece el script 30 00:01:27,500 --> 00:01:29,340 entonces, ¿cómo se crea un prefab? pues bien 31 00:01:29,340 --> 00:01:31,579 un proceso bastante sencillo, primero le tenemos que decir 32 00:01:31,579 --> 00:01:33,700 cuál es nuestro prefab, es decir, cuál es el GameObject que contiene 33 00:01:33,700 --> 00:01:35,579 el prefab, y para eso pues 34 00:01:35,579 --> 00:01:37,659 crearemos una variable, en este caso 35 00:01:37,659 --> 00:01:39,560 de tipo serializada, porque quiero acceder a ella desde Unity 36 00:01:39,560 --> 00:01:41,700 de tipo GameObject, por supuesto, y le damos 37 00:01:41,700 --> 00:01:43,640 un nombre, me da igual como MyPrefab 38 00:01:43,640 --> 00:01:45,540 indicando que este es el prefab que vamos a 39 00:01:45,540 --> 00:01:47,819 instanciar, lógicamente al ser serializada 40 00:01:47,819 --> 00:01:49,680 si fuese pública también 41 00:01:49,680 --> 00:01:51,579 ocurriría lo mismo, pues 42 00:01:51,579 --> 00:01:53,099 efectivamente veremos, voy a 43 00:01:53,099 --> 00:01:54,519 acceder, ahí está 44 00:01:54,519 --> 00:01:57,340 me está pidiendo que cabre aquí un GameObject 45 00:01:57,340 --> 00:01:59,439 que ya hemos visto varias veces, que realmente podemos buscarlo 46 00:01:59,439 --> 00:02:01,620 o arrastrarlo, y en este caso lo voy a arrastrar 47 00:02:01,620 --> 00:02:03,480 desde la ventana de proyecto, indicando 48 00:02:03,480 --> 00:02:05,540 que este es el GameObject 49 00:02:05,540 --> 00:02:06,920 que necesito 50 00:02:06,920 --> 00:02:09,379 instanciar, y una vez que ya está vinculado 51 00:02:09,379 --> 00:02:11,419 a esta variable, pues ya podemos usar 52 00:02:11,419 --> 00:02:13,099 el método que viene por defecto en Unity 53 00:02:13,099 --> 00:02:13,919 que es 54 00:02:13,919 --> 00:02:16,620 instanciar, bueno, no lo voy a pronunciar porque 55 00:02:16,620 --> 00:02:19,080 no quiero hacer el ridículo, pero es instanciar 56 00:02:19,080 --> 00:02:20,099 en inglés, ahí lo tenemos 57 00:02:20,099 --> 00:02:21,979 y bien, nos pide 58 00:02:21,979 --> 00:02:24,639 el objeto que queremos instanciar 59 00:02:24,639 --> 00:02:26,819 pues ahí lo tenemos, el que acabamos de crear 60 00:02:26,819 --> 00:02:28,259 si le doy a play 61 00:02:28,259 --> 00:02:29,840 si todo va bien 62 00:02:29,840 --> 00:02:32,360 de repente aparecerá mi prefab aquí en el centro 63 00:02:32,360 --> 00:02:34,060 ahí lo tenéis y para ahí de aquí se va 64 00:02:34,060 --> 00:02:36,500 de hecho lo voy a repetir 65 00:02:36,500 --> 00:02:38,219 fijémonos en la ventana de jerarquía como de repente 66 00:02:38,219 --> 00:02:40,479 aparece el solo una instancia 67 00:02:40,479 --> 00:02:41,020 ahí 68 00:02:41,020 --> 00:02:44,460 eso ya está bien, pero lógicamente lo ideal es 69 00:02:44,460 --> 00:02:46,479 decirle dónde quiero que lo instancie 70 00:02:46,479 --> 00:02:48,780 para eso el método de hacerlo 71 00:02:48,780 --> 00:02:50,759 es un poco dando una vuelta 72 00:02:50,759 --> 00:02:52,860 pero el prefab necesita un objeto de referencia 73 00:02:52,860 --> 00:02:55,039 es decir, decirle dónde tiene que instanciarse 74 00:02:55,039 --> 00:02:56,319 y para eso necesita algún objeto 75 00:02:56,319 --> 00:02:58,360 en la escena. Yo ya lo tengo. 76 00:02:58,740 --> 00:03:00,419 Tengo este empty object, que realmente 77 00:03:00,419 --> 00:03:01,960 no hace nada. Pues le puedo decir que una instancia aquí. 78 00:03:02,259 --> 00:03:04,039 Para eso necesito su posición. 79 00:03:04,479 --> 00:03:06,180 Y la posición en 80 00:03:06,180 --> 00:03:08,080 Unity lo marca el componente 81 00:03:08,080 --> 00:03:09,020 transformPosition. 82 00:03:10,340 --> 00:03:11,099 Pues vamos a ello. 83 00:03:12,020 --> 00:03:14,500 Voy a crear en el empty object, en el script 84 00:03:14,500 --> 00:03:15,960 que genera el prefab. 85 00:03:16,400 --> 00:03:18,520 De nuevo, también una variable 86 00:03:18,520 --> 00:03:19,740 serializada para poder acceder a ella. 87 00:03:20,060 --> 00:03:22,099 Y esta vez no es de tipo gameObject, sino de tipo transform. 88 00:03:22,900 --> 00:03:24,360 Es decir, no necesito 89 00:03:24,360 --> 00:03:26,219 un objeto completo, sino solo sus parámetros. 90 00:03:26,319 --> 00:03:36,889 transform. Y le voy a llamar, por ejemplo, initPos, de posición inicial. Y ahora, aquí, 91 00:03:37,409 --> 00:03:42,050 donde le he dicho que instancia el prefab, le digo coma y automáticamente me pide una 92 00:03:42,050 --> 00:03:47,150 variable de tipo transform, que la tengo aquí, aunque todavía no la he asociado a ningún 93 00:03:47,150 --> 00:03:53,550 objeto. Lo voy a hacer ahora, es decir, veis que aquí, donde ya había asociado el cubo, 94 00:03:53,629 --> 00:03:56,729 ahora aparece una nueva variable que es posición inicial, una variable de tipo transform, y 95 00:03:56,729 --> 00:04:00,469 le voy a decir qué parámetros de transform, pues el que tiene este objeto, y lo arrastro. 96 00:04:00,509 --> 00:04:10,750 Es decir, que ahora mismo esa variable tiene las coordenadas bien y eso significa que ahora mismo si lanzo el juego veremos que la instancia aparecerá justo donde está ese objeto. 97 00:04:10,930 --> 00:04:12,330 Ahí está. Y ya sale disparado. 98 00:04:13,409 --> 00:04:16,829 Comprobación. Voy a mover mi objeto de referencia. Lo voy a poner aquí. 99 00:04:17,670 --> 00:04:21,250 Pues ahora mismo si lo lanzo veremos que efectivamente se instancia ahí. 100 00:04:23,740 --> 00:04:25,879 Pero vamos a hacer un pequeño truco de magia. 101 00:04:26,199 --> 00:04:30,199 Yo he instanciado un objeto, pero ¿y si quiero instanciar, por ejemplo, 10 objetos cada uno en su posición? 102 00:04:30,199 --> 00:04:48,199 Bien, ahora mismo le hemos dado dos parámetros al método de instanciar, que es qué objeto, qué prefab quiero instanciar y el segundo parámetro que era de tipo transform, indicándole todos los parámetros que tiene transform, es decir, el objeto de referencia, su posición y su rotación principalmente. 103 00:04:48,199 --> 00:04:55,660 principalmente. Pero el método de instanciar permite otra modalidad, que es con tres parámetros. 104 00:04:56,420 --> 00:05:03,360 El primero, el prefab que quiero instanciar. El segundo, ya no es un objeto de tipo transform, 105 00:05:03,519 --> 00:05:11,100 sino un vector 3, es decir, una posición concreta en el espacio. Y tercero, una rotación 106 00:05:11,100 --> 00:05:15,100 concreta en el espacio, en esta casa medido con cuaterniones, que los veremos más adelante, 107 00:05:15,100 --> 00:05:17,800 pero que ahora nos tenemos que enfrentar a ellos. 108 00:05:18,120 --> 00:05:24,540 Vamos a ver cómo podemos, por ejemplo, crear un objeto en la posición donde está el objeto de referencia, 109 00:05:25,300 --> 00:05:28,420 un poquito más a la derecha, otro poquito más a la derecha, otro poquito más a la derecha, 110 00:05:28,519 --> 00:05:31,199 así 10 prefabs seguidos que lógicamente se moverán a la par. 111 00:05:31,360 --> 00:05:33,860 Vamos a hacerlo. En este caso, me voy un momentito al código, 112 00:05:34,139 --> 00:05:37,139 y algo que tenemos que entender es que esto que le he pasado aquí como segundo parámetro 113 00:05:37,139 --> 00:05:42,060 es una variable de tipo transform, es decir, que tiene tanto la posición como en rotación, escala, 114 00:05:42,259 --> 00:05:44,980 es decir, que tiene todos esos parámetros. 115 00:05:45,480 --> 00:05:49,800 Pero si yo le digo un atributo que es el de posición, esto ahora mismo es un vector 3. 116 00:05:50,220 --> 00:05:53,300 Así que me está pidiendo ahora otro parámetro, porque le he dicho dónde está la posición, 117 00:05:53,420 --> 00:05:55,139 pero le tengo que decir también cómo está la rotación. 118 00:05:55,519 --> 00:05:56,519 Eso, insisto, es un cuaternión. 119 00:05:57,319 --> 00:06:04,259 De momento, quedémonos en que la clase cuaternión admite un método muy práctico, 120 00:06:04,259 --> 00:06:07,759 que es el de identity, que significa sin rotación. 121 00:06:08,100 --> 00:06:14,000 Es decir, como si le pasásemos un objeto de tipo cuaternión, pero vacío, sin ningún tipo de rotación. 122 00:06:14,000 --> 00:06:19,660 Si yo ahora mismo lanzo, veremos que la instancia aparecerá efectivamente en el objeto referencial. 123 00:06:19,899 --> 00:06:24,120 Pues vale, y ahora quiero que prestemos atención que esto es un vector3. 124 00:06:24,420 --> 00:06:26,259 Entonces, vamos a jugar con ello. 125 00:06:26,680 --> 00:06:30,339 Voy a crear una variable, en este caso no me importa que sea privada, de tipo vector3. 126 00:06:30,480 --> 00:06:34,439 Le voy a llamar newPosition, es decir, donde se va a desplazar en cada vuelta. 127 00:06:35,639 --> 00:06:36,240 Y ya está. 128 00:06:37,339 --> 00:06:41,160 Y ahora, vamos a aplicar algo de lo aprendido anteriormente en programación, 129 00:06:41,160 --> 00:06:53,019 que es, por ejemplo, un bucle, mientras n sea 0, n sea menor que 10, súmale 1 a n, 130 00:06:54,579 --> 00:06:59,319 si yo ahora mismo pegase esta línea tal cual está a ese bucle, 131 00:07:00,199 --> 00:07:03,639 crearía 10 instancias, pero en el mismo sitio. 132 00:07:03,980 --> 00:07:06,920 Vamos a comprobarlo y además lo vamos a mirar aquí fijándonos en la jerarquía, 133 00:07:07,000 --> 00:07:10,160 porque de repente aparecerán 10, ahí están, mis 10 instancias, todas allí corriendo. 134 00:07:10,560 --> 00:07:11,560 Lógicamente eso no es lo que yo quiero. 135 00:07:11,560 --> 00:07:16,180 Lo que yo quiero es que en cada vuelta de mi bucle se cree una nueva posición. 136 00:07:17,519 --> 00:07:24,310 El newPosition, por ejemplo, es igual a la posición inicial. 137 00:07:25,850 --> 00:07:30,290 Por ejemplo, mi objeto en cada vuelta necesito sumarle una cantidad que vaya subiendo. 138 00:07:30,629 --> 00:07:31,370 Pero es que ya la tengo aquí. 139 00:07:31,930 --> 00:07:35,550 Porque aquí n vale 0, en la siguiente vuelta valdrá 1, en la siguiente vuelta valdrá... 140 00:07:35,550 --> 00:07:40,470 Entonces, lo único que tengo que hacer es crear un vector3, una nueva instancia. 141 00:07:40,470 --> 00:07:42,930 le voy a llamar cambio de posición 142 00:07:42,930 --> 00:07:45,370 y esto es un nuevo vector 3 143 00:07:45,370 --> 00:07:48,269 cuyo valor es 144 00:07:48,269 --> 00:07:50,689 n, 0 y 0 145 00:07:50,689 --> 00:07:51,430 que acabo de crear 146 00:07:51,430 --> 00:07:54,069 un vector 3 en el que en la primera vuelta 147 00:07:54,069 --> 00:07:55,209 valdrá 1, 0, 0 148 00:07:55,209 --> 00:07:57,529 en la segunda vuelta valdrá 1, 0, 0 149 00:07:57,529 --> 00:07:58,970 en la tercera 2, 0, 0 150 00:07:58,970 --> 00:08:01,990 que significa que si yo a la posición inicial 151 00:08:01,990 --> 00:08:04,389 le sumo ese vector 3 152 00:08:04,389 --> 00:08:05,790 que acabo de crear en cada vuelta 153 00:08:05,790 --> 00:08:08,110 pues en cada ciclo 154 00:08:08,110 --> 00:08:09,709 se moverá 1 en x 155 00:08:09,709 --> 00:08:11,670 la zona donde se instancia 156 00:08:11,670 --> 00:08:14,069 mi prefab, y lógicamente cuando le hemos dicho 157 00:08:14,069 --> 00:08:15,329 donde se tiene que instanciar 158 00:08:15,329 --> 00:08:17,250 pues ya no es la posición del 159 00:08:17,250 --> 00:08:19,389 objeto de referencia, sino 160 00:08:19,389 --> 00:08:21,529 la nueva posición 161 00:08:21,529 --> 00:08:24,069 vamos allá 162 00:08:24,069 --> 00:08:26,189 si todo va bien, se instanciarán 163 00:08:26,189 --> 00:08:27,550 10 prefabs 164 00:08:27,550 --> 00:08:29,350 cada uno desplazado, uno en x 165 00:08:29,350 --> 00:08:31,569 vamos a comprobarlo, ahí están 166 00:08:31,569 --> 00:08:32,570 mira, parece un tren 167 00:08:32,570 --> 00:08:36,029 en este caso he usado el valor 168 00:08:36,029 --> 00:08:37,830 de n porque lo tenía aquí, pero de nuevo 169 00:08:37,830 --> 00:08:42,970 Pero hemos aprendido cómo son los bucles, es decir, que si n no me gusta, pues yo puedo crear mi propia variable. 170 00:08:43,250 --> 00:08:53,230 Es decir, que decirle que la variable y es igual a 0 y en cada vuelta de ciclo le digo que y es y más 2. 171 00:08:53,850 --> 00:08:56,629 Os recuerdo que esto es un atajo de decirle que sume 2 a y. 172 00:08:57,870 --> 00:09:04,429 Así que aquí en vez de decirle n, pues le puedo decir y y ahora mismo se instanciarán con 2 de diferencia en el eje x. 173 00:09:04,929 --> 00:09:07,210 Vamos a ver. Ahí están. 174 00:09:07,830 --> 00:09:09,809 y todos dos desplazándose a la misma velocidad. 175 00:09:11,049 --> 00:09:14,409 Espero que entendamos toda la potencialidad que tiene esto, 176 00:09:14,409 --> 00:09:18,690 porque imaginemos que, por ejemplo, tenemos un juego de plataformas 177 00:09:18,690 --> 00:09:22,389 en las que lo que tengo que hacer es que cada cierto tiempo aparezca una plataforma nueva, 178 00:09:22,830 --> 00:09:24,990 o un juego en el que tenemos que evitar obstáculos, 179 00:09:25,090 --> 00:09:28,049 en los que les puedo decir que cada cierto tiempo aparezca un nuevo obstáculo, 180 00:09:28,590 --> 00:09:33,149 pero necesito ponerlo en una situación, a lo mejor, aleatoria. 181 00:09:33,149 --> 00:09:38,590 Me interesa que quede muy claro cómo es un prefab, sus potencialidades y cómo se instancia. 182 00:09:38,769 --> 00:09:41,350 Y ya veremos qué de cosas podemos hacer con ello.