Transcripciones
1. Introducción: Bienvenido a mi curso de Diálogo y Sistemas de eventos en Gado. Este curso es una continuación de los elementos esenciales de desarrollo de
juegos
en Gado pero se puede seguir y aplicar a cualquier proyecto que involucre
a un personaje que
el jugador pueda controlar para interactuar con NPC u objetos presionando un botón y
mostrando diálogo Te invitamos a unirte a
nuestro servidor de discordia para trabajar en este curso
junto a tus compañeros En este curso
cubriremos la creación de cuadros de diálogo, eventos
e interacciones. Luego átelos
con banderas de progreso, controles de
cámara y animaciones de
personajes. Cuando termines, tendrás un completo sistema de diálogo
y eventos para tu juego que
se puede utilizar para producir escenas de corte de
alta calidad y narrativas
complejas de ramificación que reaccionan a las elecciones de los jugadores y les
permiten
progresar en el También aprenderás habilidades útiles para trabajar con el motor de juego
Gada, organizando y diseñando tus proyectos para que
sean más escalables. Estarás
aprendiendo a codificar con script
GD con todo lo
explicado en detalle Aplicaremos principios de diseño
orientado a objetos en nuestros scripts,
herencia, encapsulación
y abstracción, junto con otros patrones de diseño de
ingeniería de software como Singleton y
Composite pattern, para mantenerlos organizados, personalizables y reutilizables
para un proyecto de cualquier tamaño Todos los archivos del proyecto
también están disponibles en Github, si necesitas revisar
el proyecto tal como estaba después de completar
cada lección. Estos videos fueron grabados
usando Gadot versión 4.2 0.2. El proyecto comienza
con activos de los packs remasterizados de
K Kits Character y
Dungeon hechos por K L auberg y el paquete básico
Guy Todos están disponibles para
descargar gratis en dot IO.
2. Cuadro de diálogo: Hola, amigos. Antes de que
empecemos, deberías tener un juego visto
en tu proyecto que contenga un personaje que el jugador pueda controlar y un nivel en el que
puedan caminar. Debes tener otros
personajes para actuar como NPC u objetos con los que el
personaje pueda interactuar A lo largo de este curso,
agregaremos la capacidad para que
el jugador interactúe con el entorno
pulsando un botón, ya sea para iniciar
un diálogo con otro personaje o
interactuar con un objeto. Estas interacciones incluirán al jugador
progresando en el juego, tomando decisiones y creando escenas
básicas de corte con comportamientos y animaciones de
cámara personalizados comportamientos y animaciones de
cámara Puedes usar tu propio proyecto para seguir junto con este
curso o descargar un proyecto de inicio
de mi Github titulado Godo Dialog Course Main Branch Tu proyecto puede ser
dos D o tres D y casi cualquier
género de juego que involucre al jugador interactuando con
el entorno o NBCs Comencemos agregando un
cuadro de diálogo a la escena del juego. Dependiendo de los
activos que esté utilizando, posible
que desee convertir
el nodo raíz
del cuadro de diálogo en un panel
o un contenedor de panel. Pero estos activos son tan grandes que quiero
escalarlos hacia abajo, lo que requerirá que
el nodo
de panel no tenga hijos, ya que la escala
sería heredada, y no quiero eso. Es posible que desee que el
cuadro de diálogo sea visible sobre el FAD
por razones artísticas Realmente depende de
cómo lo quieras usar. Voy a tener el mío dibujado primero detrás de todo lo
demás en la interfaz de usuario. Con mis diálogos nodo raíz, solo un simple
nodo de control que
en realidad no representa
nada dibujado en pantalla Anclaré el diálogo a
la parte inferior de la pantalla, cubriendo todo el
ancho y configuraré el anclaje superior a dos tercios hacia abajo desde la parte superior de la pantalla. El cuadro de diálogo cubrirá el tercio
inferior de la pantalla, que con mi tamaño de ventana
es de alrededor de 240 píxeles. Entonces agregaré un nodo hijo, un panel para dibujar el cuadro
real en la pantalla, y configuraré sus anclajes en naufragio completo,
para que coincida con su padre Dando un nuevo tema al nodo del
grupo de diálogo. Podemos agregar un panel
al tema y
darle una nueva
textura de caja de estilo para dibujarlo. Voy a usar caja naranja redondeada
como la textura de mi cuadro de diálogo con márgenes de
textura de 256
píxeles en todos los lados. Esta imagen es enorme
con 1522 píxeles. Voy a escalar el
nodo a la mitad de tamaño. A continuación, use el ajuste de cuadrícula y establezca sus dimensiones para que coincidan con
el nodo padre del diálogo La mayoría de los cuadros de diálogo
contendrán al menos
el nombre de la persona que está hablando y una línea de diálogo
dispuesta verticalmente. Agreguemos un
contenedor de caja vertical y dentro de eso, también agreguemos dos etiquetas. Uno por el nombre del orador y otro para una
línea de diálogo. Pero para la línea de diálogo, es posible que desee usar
una etiqueta de texto enriquecido en lugar de una etiqueta normal. Las etiquetas de texto enriquecido
permiten el uso de código
BB para hacer todo tipo de trucos de formato
a su texto de diálogo, como negrita, cursiva o incluso colores y animaciones Puedes expresar el
tono del orador, asociar temas relacionados
con colores únicos o resaltar palabras clave importantes para ayudar al jugador a
recordarlas. Voy a cambiar el tamaño del cuadro
vertical para que quepa dentro de los límites
del cuadro de diálogo Tiendo a usar la
ortografía estadounidense del diálogo cuando refiero a una interfaz de
interfaz de usuario que muestra texto. Pero usaré la
ortografía tradicional del diálogo cuando refiero a una conversación entre personajes de una escena. Vamos a rellenar estos con
algún texto de marcador para que podamos ver cómo se ven Alguien está hablando, y
están diciendo algo de oram Ipsum. Al activar el
contenido de ajuste,
el nodo de etiqueta de texto enriquecido se expandirá para
ajustarse a su contenido como lo haría un nodo de etiqueta
normal. Vamos a establecer la fuente predeterminada
y el tamaño de fuente para el tema, usando la
fuente más legible como predeterminada con un tamaño razonable que sea
fácil de leer. Voy a usar 32. Al agregar una
etiqueta de texto enriquecido al tema, podemos establecer el color predeterminado para la línea de diálogo y no el nombre del orador ya que son diferentes tipos de nodos. Voy a usar el negro para
destacar mejor contra
la caja naranja. Después podemos agregar el nodo de
etiqueta al tema y usar una fuente diferente para
mostrar el nombre del orador. También voy a dar a las
etiquetas de nombre un
color diferente y una sombra, así que sobresale aún más. Usaré una fuente más elegante para
la etiqueta del nombre del orador. Antes de escribir cualquier
diálogo para tu juego, es una buena idea obtener
una estimación aproximada de la
cantidad de texto que
cabe cómodamente en la pantalla en tu juego. Asegúrese de que su cuadro de diálogo
sea capaz de mostrar una cantidad razonable de texto sin
dejar de ser
fácilmente legible. Usando
textos de marcador de posición falsos como este, podemos llegar a un
peor escenario de la cantidad de texto que podemos mostrar y usarlo como un límite duro al escribir
diálogos para el juego También debe
haber alguna indicación al jugador de que el
diálogo ha terminado, y el juego está esperando que
su aporte continúe. Agreguemos un botón
al cuadro de diálogo. Como quiero que la textura de
los botones coincida con la escala
de la textura de la caja, tendré como hijo de la caja y la anclaré
a la parte inferior derecha. Este es un botón único, así que en lugar de establecer su cuadro de
estilo en el tema, usaré la sección de
anulación de tema para agregar un nuevo
cuadro de estilo de textura que
solo se aplicará a este botón
específico. Voy a usar el icono de flecha. Usa las dimensiones en píxeles de la imagen para definir
el tamaño del botón y colóquelo
donde se vea bien. Crearé más cuadros de estilo para los otros estados de botón
usando el mismo icono de flecha. Luego aplique modulación de color
para cada otro estado. Gris descolorido para discapacitados, colores
verde y amarillo para los demás. La tematización para botones
todavía está disponible si
queremos usarla
más tarde para agregar botones temáticos al cuadro de diálogo sin
afectar a este botón Asegúrate de verificar
cómo
aparece tu cuadro de diálogo en el
contexto del juego y haz los ajustes
necesarios hasta que estés
satisfecho con su aspecto. Una vez que esté satisfecho
con su cuadro de diálogo, podemos ocultarlo por
defecto haciendo clic en el icono al lado del mismo
en el árbol de escenas. A continuación, vamos a agregarle un script y guardarlo en la carpeta de scripts de la
interfaz de usuario. Tomemos una referencia
tanto a la etiqueta del orador como a
la etiqueta de texto enriquecido del diálogo, asignándolos a variables
privadas Nuestro guión necesita
poder mostrar cualquier línea de diálogo hablada por
cualquier orador en nuestro juego, lo
que significa que
necesitará una función pública acepte dos parámetros, quién está hablando
y qué está diciendo. Ambos como cuerdas. Ambos se pueden establecer accediendo a
la propiedad text, asignándola al parámetro
pasado a la función En versiones anteriores de Godot, la etiqueta de texto enriquecido tendrá propiedades
separadas para
texto y texto en código BB Asegúrate de que estás usando
la propiedad de texto de código BB si quieres que tu código
BB funcione. Podemos hacer esto más funcional
haciendo que el
altavoz sea opcional, configurando la propiedad visible
de la etiqueta del altavoz para que dependa de si el nombre del hablante
es o no una cadena vacía. Si intercambiamos el orden
de los parámetros, también
podemos hacer que el
parámetro sea opcional
asignando un valor predeterminado
de una cadena vacía Los parámetros opcionales siempre se
deben
enumerar después de los obligatorios
al definir una función. También debemos establecer la
propiedad visible del cuadro de diálogo. Hagámoslo en una función
pública separada llamada open. Y también una función cerrada
para establecerla en false. Agarrando una referencia al botón
continuar también. Después de que se
haya visualizado el texto, debemos decirle al botón de
continuación que tome el
foco para que se pueda acceder a él
con un controlador. Conectemos la señal del botón
pulsado al guión, y utilicémosla para cerrar el cuadro de
diálogo por ahora. En el guión del administrador del juego, podemos agarrar una referencia
al cuadro de diálogo. Cuando el juego comienza por primera vez, podemos decirle al cuadro de
diálogo que muestre un mensaje. Hola Mundo. Dado que el
nombre del orador es opcional, veamos cómo
funciona sin él. Esta vez, agreguemos un nombre de
orador, fantasma. El fantasma dirá, Boo, soy un fantasma aterrador, pero tendrá algún código
BB aplicado, así que el jugador
tendrá una mejor idea de cómo se
pretende leer la línea. Si sus etiquetas dejan los confines del área, se
cortarán Pero podemos cambiar
ese comportamiento en las propiedades de control
desmarcando el contenido del clip Hay muchas etiquetas de código BB
diferentes que proporcionan una amplia
variedad de efectos, e incluso puedes
crear las tuyas propias usando un script personalizado que hereda del efecto
de texto enriquecido Para obtener una lista completa de etiquetas de código BB, consulte Google Docs. Ahora podemos mostrar
un cuadro de diálogo para dar información al jugador. En la siguiente lección, agregaremos una animación de mecanografía y mostraremos
secuencias de diálogo. Te veré en la siguiente lección.
3. Monólogo: Hola, amigos. En
la lección anterior, agregamos un
cuadro de diálogo a la escena del juego. En esta lección,
animaremos la escritura, para que el texto aparezca
gradualmente y permita que el cuadro muestre
secuencias de diálogo Para fines de demostración, lo
he vuelto a referir a usar Guram Ipsum para esta lección y haré visible el cuadro de
diálogo Con el nodo de etiqueta de
texto enriquecido de diálogo seleccionado, expanda la sección de
texto que se muestra. Podemos ver que el número
de caracteres visibles es una propiedad fácilmente editable con un valor predeterminado
de uno negativo Negativo uno
caracteres visibles es obviamente imposible y se está
utilizando para significar ilimitado. Pero si ajustamos este número haciendo clic y
arrastrándolo lentamente hacia la derecha, podemos ver que el texto desaparece
y se rellena gradualmente a medida el número de caracteres visibles aumenta de cero a
la longitud de la cadena En nuestro script de diálogo, cuando configuramos el texto
que se muestra, también
podemos establecer los
caracteres visibles en cero. Luego queremos aumentar el
número de caracteres visibles gradualmente con el tiempo hasta que todos los personajes
sean visibles. Como no sabemos
cuántos caracteres hay, podemos usar un bucle wile para seguir repitiendo el mismo código
siempre y cuando se cumpla la condición La condición, en este caso
será siempre que el número de caracteres
visibles sea
menor que el número total
de caracteres. Comprobando la documentación
para el nodo de etiqueta de texto enriquecido. Podemos ver que
existe una función llamada get total
character count, que convenientemente devuelve
el número total de caracteres excluyendo etiquetas de código
BB. Si bien el número de caracteres
visibles es menor que el recuento total de
caracteres, podemos agregar uno a los caracteres
visibles. Pero este bucle y
toda la función
van a correr en el
lapso de un solo fotograma. Todo el texto aún
se mostrará instantáneamente. Necesitamos decirle al bucle pausa por un breve
tiempo en cada iteración. Podemos decirle al bucle que aguarde una señal emitida
por el árbol de escenas, una señal que se emite una
vez cada fotograma de proceso, 60 veces por segundo con la configuración
predeterminada del proyecto. Este bucle ahora
mostrará los caracteres a una velocidad de 60 caracteres por segundo y se
ajustará automáticamente con la
configuración de velocidad de fotogramas del proyecto. Pero, ¿y si no queremos
usar la velocidad de fotogramas de los proyectos? L et's en su lugar agrega una variable de velocidad de
escritura
al recurso de configuración y le da un valor predeterminado de
90 caracteres por segundo. En la escena del menú de configuración, podemos agregar una etiqueta y un control deslizante para permitir que el reproductor
cambie la velocidad de escritura. Y darle un rango razonable. Lo configuraré en
30-120 caracteres por segundo con un valor de
paso de diez Conecte su
señal de valor cambiado al script. Y cambie el recurso de
configuración para que coincida e inicialice el
valor en la función ready Consulta el curso
esencial de desarrollo de juegos en esta serie para
obtener más información sobre la configuración del juego. De vuelta en el script del cuadro de diálogo, necesitaremos una variable para retener cuánto tiempo ha
pasado desde que
comenzó la escritura y ponerla a cero
antes de que comience el ciclo de escritura. Entonces en cada iteración de bucle, podemos sumar la
cantidad de tiempo que ha pasado accediendo a
la función, obtener proceso Delta T. Ya que sabemos cuántos
segundos han pasado desde que comenzó
la tipificación y
cuántos caracteres queremos escribir por segundo, solo
necesitamos multiplicar
estos dos números juntos para que el número
de caracteres Veamos cómo se ve. Incluso podemos cambiar la
velocidad de escritura en la configuración del juego. El registro de depuración nos dice que
estamos estrechando la precisión, convirtiendo un float
en un entero Podríamos o convertir
la velocidad de escritura en un flotador o ignorar esta advertencia ya que
sabemos que el deslizador estaba configurado para
usar solo enteros de todos modos Entonces agregaré una
etiqueta de advertencia de ignorar antes de esta línea. Godo sabe ignorar la advertencia de precisión de
estrechamiento. Esto también sucede en el script del menú de
configuración
por el mismo motivo. Ahora la velocidad de escritura
es un poco más rápida, pero es posible que algunos jugadores aún quieran saltarse la animación de
mecanografía. Entonces cambiemos el comportamiento
del botón de continuación. Si el jugador presiona el botón de
continuación
y el número de caracteres
visibles es
menor que el recuento total de caracteres, podemos
establecer instantáneamente el número de caracteres
visibles igual
al recuento total de caracteres. Esto mostrará
todo el texto y obligará al bucle wile a romperse ya que su condición ya no
se cumple Si el número de caracteres
visibles
no es menor que el recuento
total de caracteres, eso significa que la escritura ya
ha terminado. En ese caso, deberíamos
cerrar el cuadro de diálogo. Para que esto funcione
con un controlador, el botón continuar necesitará
tomar el foco antes de que comience
la escritura. Cuando se inicia la
animación de mecanografía y el jugador presiona el botón continuar, bien omitirá
la animación de mecanografía o cerrará el cuadro de
diálogo, no ambos. Saltarse la
animación de mecanografía aún le dará al jugador la
oportunidad de leerla antes de seguir adelante Pero, ¿y si queremos que
un personaje diga más de una línea de diálogo y mantenga abierto el cuadro de diálogo? Para eso, podemos agregar
otra función pública para mostrar diálogo. Esta vez, aceptando una matriz de cadenas como
primer argumento. Comencemos simplemente llamando nuestra otra función para
mostrar la primera línea, usando Índice cero en la matriz, pasándola y el nombre
del
orador para que se escriba en
el cuadro de diálogo Para luego continuar hacia la segunda línea cuando se presiona el botón de
continuar, necesitaremos el guión
para recordar cuáles son
las líneas y qué línea
se muestra actualmente. Dado que el alcance de esta matriz está solo dentro del contexto
de esta llamada a la función, no
se puede acceder a ella
desde otra función. Entonces declarando una nueva
variable de líneas, una matriz de cadenas, podemos asignar su valor en
la parte superior de la nueva función, y otra variable
para recordar qué línea se
muestra actualmente como un entero Podemos establecerlo a cero en la parte superior de la llamada a la
función también, y usarlo para indexar la matriz. Entonces cuando se presiona el
botón de continuación, podemos agregarle uno, luego verificar si aún es menor que el tamaño de la matriz. Si lo es, entonces
hay más diálogo, para que podamos volver a llamar a la
primera función. Cambiando esto para que sea
la variable privada, que declaramos anteriormente
y usamos para almacenar una matriz de cadenas pasadas a la función
multilínea pública. Si quieres que se
siga mostrando el nombre del orador , también
tendrás que almacenarlo
en una variable. Y si no, entonces el
diálogo está terminado, y podemos ocultar
el cuadro de diálogo. Pero ahora el
botón de continuar no funcionará como se esperaba si solo mostramos
una sola línea de diálogo. Tendremos que separar la funcionalidad pública de mostrar una línea de diálogo de los detalles de cómo se logra creando un método
privado que haga el. Las funciones públicas, ya sea aceptando una línea
o múltiples líneas, ahora
pueden llamar a
la función privada para lograr sus
objetivos internamente. La primera función puede
almacenar la línea única en la matriz como su único contenido y establecer la
línea actual en cero, y ahora se comporta exactamente
como la función multilínea Pero ya seas
tú o alguien más escribiendo los
guiones de diálogo para tu juego, ahora
existen
múltiples opciones para mostrar una sola línea o
varias líneas de diálogo. Abrir el cuadro de diálogo
y captar el foco solo necesita hacerse una vez para que se muestre
cada conjunto
de diálogo Y el
botón de continuar solo necesita llamar
a la
función de siguiente línea también. Normalmente me gusta organizar funciones en mis guiones
para tener públicas en la parte superior y privadas en la parte inferior y mantener juntas
las funciones relacionadas. Esto sigue dos
principios orientados a objetos, Abstracción, ocultar los detalles de cómo
se hacen las cosas de forma privada
dentro del script, y encapsulación, solo exponiendo públicamente las funciones que
desea que otros vean y usen Intentemos simular a un personaje hablando múltiples
líneas de diálogo Primero, declararemos
una variable para mantener una secuencia de diálogo
en una matriz de cadenas y pasarla a la llamada a la función
como primer argumento, que rellenaremos
abriendo un corchete Pero como la secuencia de múltiples cuerdas largas
ocupará bastante espacio,
prefiero tener a cada una de
ellas en su propia línea, y ayuda usar la sangría
para mantenerlas organizadas. Entonces se puede
usar el
corchete de cierre para marcar claramente
dónde termina esta matriz. Ejecutando la escena, podemos ver que se muestra la primera
línea. Al hacer clic en el
botón de continuación se muestra la siguiente línea, hacer clic en el botón de continuación mientras la línea aún está escribiendo, omitiremos la animación y mostraremos la línea completa. Cuando se
han visualizado las cuatro líneas, hacer clic en el
botón de continuación se cierra el cuadro de diálogo. Pero no quiero tener que
declarar una variable, rellenarla y llamar a
una función cada vez Preferiría hacerlo
todo en una sola línea de código. Siguiendo un formato similar, podemos reemplazar la declaración de la
variable con la llamada a la función Los paréntesis agregan otra capa
de sangría Nuestra matriz se declara
y se rellena dentro de la llamada a la función junto con especificar el nombre del
hablante. Sin embargo, la matriz ahora no
tiene un tipo especificado, pero como Godo Script es un
lenguaje poco escrito, esto De hecho, podemos eliminar
los requisitos de tipo de nuestros parámetros de
función de script de diálogo. Pero ten cuidado de solo pasar argumentos
válidos o
obtendrás errores. Ahora podemos mostrar secuencias de
diálogo
más largas con
mecanografía animada y saltos. En la siguiente lección, crearemos scripts de eventos
personalizados que pueden mostrar
secuencias complejas de diálogo. Te veré en la siguiente lección.
4. Gerente de eventos: Hola, amigos. En
la lección anterior, mejoramos el
sistema de diálogo con mecanografía, saltos y múltiples líneas En esta lección, crearemos
un gestor de eventos para manejar nuestro diálogo de juegos y
sincronizarlo con otros sistemas Comenzando en la escena del juego, agreguemos un nuevo nodo básico y le pongamos el nombre Administrador de eventos. El script del administrador del juego puede obtener una referencia a este nodo
usando add on ready, junto con el nodo jugador. Pensando en el árbol de escenas como una organización, normalmente, si diferentes ramas quieren solicitar algo
entre sí, necesitan enviar la solicitud a través de un gerente
por encima de ambas. En este caso, algo en el nivel va
directo a la cima del
gestor de escena
del juego para solicitar permiso para usar el
gestor de eventos para ejecutar un evento. Si algo en nuestra escena de juego quiere desencadenar que ocurra un
evento, solo
necesitan pedirle al
administrador del juego que inicie un evento, pasando el evento
como argumento, y es posible que también queramos
terminar los eventos con una función
común también. El administrador del juego puede
desactivar el nodo del jugador, por lo que el jugador no puede controlar al personaje durante un evento. Y cuando termine el evento,
podremos restaurar el control del
jugador. Una vez
que se hayan hecho todos los preparativos, dígale al evento que
son buenos para correr, pasando la referencia del
gestor de eventos. Puede hacer esto más
flexible agregando también un parámetro booleano opcional a la llamada a la función con el valor
predeterminado de true Ahora es posible escribir algunos eventos que no
quiten el control del jugador. En el guión del reproductor, agreguemos una variable pública para habilitar y deshabilitar el control
del jugador En las mismas líneas donde
estamos comprobando si el juego está pausado
antes de procesar la entrada, podemos agregar una condición usando el operador u lógico
representado por dos pipas Si el juego está en pausa o el
jugador ha sido desactivado, regresamos e ignoramos la entrada Pero si el personaje se mueve cuando el
nodo jugador está deshabilitado, continuará corriendo en la misma dirección hasta que se vuelva a activar el
control. Podemos definir cómo se establece
una variable, así
como agregar
funcionalidad automática con un setter Después de una
declaración de variable con dos puntos, podemos escribir un bloque
de código para
restringir mejor cómo se accede a esta
variable Creando una función set, aceptando un nuevo valor
como parámetro, podemos asignar el nuevo
valor a nuestra variable. Pero también queremos asegurarnos de que si el nodo jugador no
está habilitado, que le digamos al
personaje que deje de moverse. Este comportamiento se vuelve automático cada vez que la
variable habilitada se establece en false. Similar a un gestor de escena, el
trabajo del gestor de eventos será
facilitar la comunicación entre diferentes
partes de la escena. Pero este guión no tiene las
mismas responsabilidades que un gestor de escena, por lo que no heredará
de esa clase Simplemente puede heredar del nodo. Todavía lo guardaré en
la carpeta del encargado,
sin embargo, ya que todavía se le
considera un gerente. En la parte superior del guión, necesitaremos referencias
a cualquier cosa que pueda estar comúnmente
involucrada en un evento. El personaje, el cuadro de diálogo, y el FAD, todo son variables
públicas También es posible que desee
agregar funciones adicionales
al administrador de eventos para agrupar comportamientos de
uso común, construir una cola de eventos o incluso anidar eventos
dentro de otros eventos. Ahora, cualquier guión en nuestra
escena de juego solo necesitará hacer
referencia al administrador del juego para
poder
iniciar un evento,
presentar diálogos, desvanecerse de entrada y salida, e incluso controlar al personaje. L et's cambian a la escena de
nivel y configuran un escenario básico donde cuando
el jugador entra a esta sala, se
les presenta
un mensaje. Para ello, necesitaremos
un nodo D de área tres con forma de colisión. Voy a hacer que sea una caja que cubra toda
la puerta de
entrada a la habitación, así que no hay forma de que
el jugador pueda entrar la habitación sin
chocar con esta Ten en cuenta que este
tipo de
eventos desencadenados por proximidad pueden ser disruptivos para algunos jugadores y deben
usarse con moderación La mayoría de los jugadores prefieren
entrar en eventos que quitan su control voluntariamente
presionando un botón. No necesita existir
en ninguna capa de colisión, enmascarando solo para colisiones
con el jugador Solo necesita
estar monitoreando para el jugador y no
monitoreable por Podemos adjuntar un script Y hacer una nueva carpeta restaurando
todos nuestros scripts de eventos. T's name it enter room, conectando el cuerpo ingresado
señal al guión, Podemos escribir lo que
sucederá cuando el personaje jugador
entre en esta área. Podemos encontrar al manager del juego usando el signo de dólar una notación, comenzando desde el nodo raíz. Podemos decirle al
manager del juego que inicie un evento, pasándose a sí mismo como argumento como el evento que
se va a iniciar. Es posible que desee hacer
esto usando ad on ready, pero recomendaría hacerlo cuando se active el evento. Ya que no todos los eventos se
activarán cada vez que se
cargue un nivel en tu juego, así que no es necesario que
busquen el
árbol de escenas de una vez, cuando sería más eficiente hacerlo solo si lo necesitan. Como no necesitamos
la referencia del cuerpo, prefijémosla
con un guión bajo al mercado para el motor Antes de iniciar el evento, también
podemos
verificar dos veces para asegurarnos de que
lo que se pasó como
argumento no es nulo. Y si no es nulo, también asegúrate de que tenga
un método llamado run event. Revirtiendo la lógica,
podemos verificar si esto es nulo o si no tiene
el método run event. Si alguna de estas
condiciones es cierta, podemos regresar
ignorando la solicitud Prefiero usar si
no evento aquí, lo que significa lo mismo. También vamos a imprimir
un mensaje de advertencia al desarrollador sobre esto, diciéndoles que han cometido un error que necesitan corregir. advertencia push mostrará un mensaje de advertencia amarillo en el registro sin
interrumpir el juego El script de eventos ahora puede definir esta función de evento de ejecución
como una serie de instrucciones que pasan
a través del administrador de eventos a cualquiera de los otros
componentes de la escena según sea necesario, y todo
se puede sincronizar mediante el uso de señales. Para crear nuestro escenario, solo
necesitamos pasar por
el gestor de eventos para acceder
al cuadro de diálogo y decirle
que muestre un mensaje. Entonces dígale al manager del juego
que el evento ha terminado. Añadiendo un peso al
frente de cualquier función, podemos devolver una señal de ella, para que el evento sepa cuándo se completa
esta tarea. Cambiando al script del cuadro de
diálogo, tengamos la función de
línea de visualización,
devolvamos una señal para cuando termine
el diálogo. Y también hacer lo mismo para
la función multilínea. En la parte superior del guión, podemos darle una definición a la
señal, y emitirla al cerrar
el cuadro de diálogo. El objetivo principal de toda
esta infraestructura es
crear guiones que se lean un
poco como un guión, dando instrucciones claras
de quién está diciendo, cómo están actuando,
dónde están parados, qué está
mirando la cámara, etcétera Si el jugador entra en esta sala, ahora
se le presenta
un mensaje. El control se ha
quitado
temporalmente al jugador mientras se muestra
el mensaje. Al presionar el botón de
continuación, el cuadro de diálogo emite la señal de que el
diálogo está completo, permitiendo que el
guión del evento avance, finalizando el evento, restaurando el
control de nuevo al jugador Ahora tenemos un
administrador de eventos que desactiva control
del jugador mientras se
desarrolla un evento que involucra diálogo En la siguiente lección, crearemos un componente interactable con
el que el jugador pueda
interactuar para desencadenar eventos Te veré en la siguiente lección.
5. Interact: Hola, amigos. En
la lección anterior, agregamos un gestor de eventos
que puede ejecutar un script de eventos. En esta lección agregaremos interacciones para que el
jugador inicie. Una forma más popular de
iniciar eventos es cuando el jugador presiona un botón para interactuar con
algo o alguien. Abrir la configuración del proyecto, cambiar a la pestaña de mapa de entrada. Agreguemos un botón de interacción. Voy a usar E en el teclado
o Y en mi Controller. Después en el guión del jugador, podremos comprobar si se presionó el
botón de interactuar, y si es así, decirle al personaje interactúe con lo que sea o con
quien esté frente a ellos. Para averiguar quién o qué sería
eso, podemos usar a. en la escena del personaje,
agreguemos un nodo hijo a la
plataforma de tipo tres D. Queremos que el rayo apunte
frente al personaje, una distancia razonable para poder interactuar
con algo, lo
pondré en 2 metros. Dado que la plataforma es lo
que en realidad está rotando, de niño, el raycast
rotará con él La máscara de colisión determina con
qué puede chocar el rayo Queremos que este rayo
encuentre interacciones. Deberíamos dar a las interacciones
su propia capa de colisión. Abriendo la configuración del
proyecto en la pestaña general,
bajo nombres de capa, tres capas de física D, estableceré la capa cinco para que sea
específicamente para interacciones. El lanzamiento de rayos
chocará con la capa cinco, pero también será obstruido
por la Capa uno, evitando que el jugador
interactúe con algo del
otro lado de una pared Ampliando la sección de
ancho de colisiones, buscaremos ambas áreas, nuestras interacciones y
cuerpos como terreno Posicionando la altura
del rayo proyectado, el sentido más
lógico colocarlo en algún lugar
alrededor del nivel de los hombros, o al menos en algún lugar
entre el nivel del pecho y los ojos. Pero también podemos usar esto
como una oportunidad para implementar ciertas
restricciones de rango en nuestras interacciones. Coloquemos la caja CSG
frente al personaje e imaginemos que nuestro objeto
interactable o NPC está encima ¿Qué tan alta puede
ser la caja antes de que la persona o cosa encima de ella ya
no sea interactable Ya que el rayo chocaría con la caja y no con la
cosa encima de ella. Creo que es razonable
permitir interactuar con algo que es 1 metro
más alto que el personaje, pero no 1.5 metros. Entonces lo colocaré en
algún lugar intermedio. 1.3 metros parece bueno, que es la mitad de la altura
del colisionador del personaje En el
guión del personaje, podemos tomar una referencia al
nodo de reparto usando add on ready. Pero tenga en cuenta que
hacerlo de esta manera
requerirá que cada personaje
tenga el nodo de reparto. Al cambiar la anotación del
signo de dólar a una función, obtener nodo o nulo Podemos pasar la ruta del nodo
como un argumento de cadena, que podemos copiar haciendo clic
derecho en el nodo
y seleccionando copiar ruta, o hacer clic y arrastrar el nodo directamente
entre comillas. Ahora para cualquier personaje
sin un nodo de reparto, esta variable
solo se establecerá en
null en lugar de
generar un error. L et's agregan una función al guión
del personaje
llamada interact, que llamamos desde
el guión del jugador cuando se presionó el
botón de interacción. Primero, comprobando si
el nodo cast existe, entonces
podemos verificar si está
colisionando con algo Entonces podemos verificar si con
qué
colisionó el elenco de rayos tiene un
método llamado interact, y si es así, llamarlo Si el elenco de rayos no
existe, no pasará nada. Si el elenco de rayos no está pegando
nada, no pasará nada. Si el rayo fundido está golpeando
terreno como una pared, el terreno
no tendrá un método llamado interactuar, por lo que
no pasará nada. Si el raycast está golpeando
algo en la capa cinco, que tiene un método
llamado interact, llamará a ese método, desencadenando un evento de interacción Pero pensando en todas
las muchas cosas diferentes en un juego con el que el jugador
podría interactuar, un NPC y una puerta son ambos interaccionables
presionando un botón, pero no comparten
mucho más Un PNJ podría querer heredar
las mismas propiedades y comportamientos utilizados por un personaje jugable para
caminar Mientras que una puerta necesita propiedades
como si
está cerrada o no y comportamientos
como abrir o cerrar. Usando una estructura de herencia. Podrías convertir todas las puertas en NPC que simplemente
no se mueven o convertir todos los personajes en puertas con sus
comportamientos y
propiedades similares a puertas ignoradas Usar el
comportamiento interactable como padre abstracto tanto de
puertas como de NPC es mejor, pero aún implica que todos los NPC y todas las puertas
deben ser interactables, que a menudo no es Es posible que desee
tener una clase NPC que herede del carácter, pero que también herede
de otra clase para obtener funciones adicionales
de Pero Godot no permite la herencia
múltiple. Sería mejor que
el comportamiento interactable de las puertas, los PNJ y cualquier otra cosa fuera independiente de la naturaleza de la cosa con la
que estás En su lugar, podemos aplicar el patrón compuesto para lograr esto de manera
más eficiente. Creando un nodo hijo para
representar la interacción, entonces
podemos adjuntar un comportamiento de
interacción
a lo que queramos. En nuestro nivel, tenemos
algunos personajes diferentes. Escojamos uno y adjuntemos un nodo
hijo a él para representar el componente de interacción de este NPC como un nodo D de
área tres Esta zona no estará
monitoreando para nada, sino que será monitoreable por el elenco de rayos que
creamos antes Por lo tanto, su
capa de colisión será de cinco, lo que puede ser detectada
por el rayo fundido y su máscara puede ser cero
ya que no está buscando nada. Necesitará una forma de colisión. Usaré una cápsula y la tendré más grande
que el personaje. El rayo no
necesita estar
apuntando exactamente directamente a ellos. En cuanto a la altura
de la cápsula, podemos aplicar la
misma lógica que antes hicimos a la inversa. Esta vez, imagina que nuestro personaje
está parado sobre la caja. ¿Qué tan alta puede ser la caja
antes de que a nuestro personaje ya
no se le permita interactuar con el PNJ parado
en el suelo Pondré las mismas
restricciones y dejaré que el jugador interactúe con
algo a 1 metro por debajo de ellas, pero no a 1.5 metros. Sabiendo que el rayo
se está lanzando 1.3 metros sobre el suelo en
el que el personaje jugador
está parado, entonces la forma de
colisión de interacciones estará en esa t más 1 metro. Hacerle 2.6 metros de
altura parece razonable, que también pasa a ser la misma altura que el colisionador del
personaje Pero tenga en cuenta que incluso un objeto minúsculo como una llave sentada en el suelo, necesitará tener un colisionador, así de alto para ser
golpeado por la refundición Podemos adjuntar un guión
a esta interacción. Vamos a llamarlo diálogo de magos. Y guárdala en la carpeta de scripts de
eventos. Este script
necesitará dos funciones, interactuar y ejecutar evento. La función de interacción será muy similar a la lección
anterior, pidiéndole al administrador del juego que
ejecute este script como un evento. Para la función run event, podemos hacer que el mage
diga lo que queramos. Y terminar el evento después de
que terminen de platicar. Ahora vamos a duplicar
este nodo de interacción y adjuntarlo a la puerta. Después también duplique el guión del diálogo
Mage y llámalo puerta celular. Reemplazando el guión adjunto
a esta interacción, luego editarlo para decir algo así
como que la puerta está cerrada con llave. En solo unos sencillos pasos, somos capaces de crear cualquier tipo de interacción que el jugador pueda iniciar pulsando
el botón de interacción con cualquier objeto o NPC Como modifiqué la escala de un muro ordinario para
crear la puerta, la forma de colisión
hereda su propiedad de escala Pero después de
centrarlo dentro de la puerta, todavía hace un buen trabajo al abarcar
la Vamos a probarlo. Presionar
el botón de interacción cuando no nos enfrentamos a
nada no sirve. Pero si caminamos hacia el mago, podemos presionar el
botón de interactuar para iniciar un diálogo. De igual manera, también podemos caminar hasta la puerta
e interactuar con ella. Ahora tenemos una puerta, el
jugador aún no puede abrir, y en NPC, el jugador puede
hablar con él presionando un botón En la siguiente lección, agregaremos opciones de
diálogo y árboles de
conversación al sistema de diálogo. Te veré en la siguiente lección.
6. Elección: Hola, amigos. En
la lección anterior, creamos un componente de
interacción que se puede adjuntar a
cualquier cosa en nuestro juego. En esta lección,
agregaremos opciones de
diálogo de ramificación al sistema
de cuadro de diálogo Primero, necesitaremos agregar más botones
al cuadro de diálogo. Depende de ti cómo
y dónde quieres posicionar tus botones de opción de
diálogo. Ya sea que estén en
el mismo
cuadro de diálogo , un cuadro separado, flotando en el
centro de la pantalla, acompañados de diálogo o no. Para mi juego, tendré mis botones dentro
del cuadro de diálogo. Agregar otro contenedor de cuadro
vertical al cuadro de diálogo. L et's name it options, y contendrá tres
botones llamados opción cero, opción uno y opción dos. Voy a dar a cada uno de ellos
algún texto predeterminado y estableceré su texto para
que quede alineado a la izquierda. Si escondo el nombre del orador y restringo el diálogo a
un máximo de dos líneas, todo debería
caber dentro de la caja. Simplemente lo anclaré a
la parte inferior derecha
del cuadro de diálogo y lo
moveré a una posición
donde se vea bien. mantener presionada la tecla alt u
opciones mientras haces clic y arrastras, solo se moverá el nodo
seleccionado y sus hijos Editando el cuadro de diálogo ellos, podemos agregar para botones. Voy a tener el color de
fuente predeterminado negro. Deshabilitado, gris descolorido. Enfocado cubierto y
presionado todo en blanco, y agrega un contorno negro, por lo que el texto blanco
sigue siendo legible. En la pestaña Constanza, estableceré el contorno
en dos puntos A continuación, reemplazaré todos los cuadros de estilo de los
botones por cuadros de estilo vacíos, para que solo se muestren
como texto normal. Seleccionando el contenedor de cuadro
vertical Opciones, usaré la sección de
anulación de tema para agregar 12 píxeles de separación entre cada uno de los
botones de opción para espaciarlos. Tómese un tiempo para organizar el diseño de
su cuadro de diálogo y use texto de marcador de posición
falso para probar los límites de
cuánta información se
puede mostrar a la vez, incluyendo cuántas opciones le gustaría
presentar al reproductor Una vez que esté satisfecho con cómo se muestra
todo, recuerde ocultar el cuadro de diálogo. Tendremos que alterar
el guión para
poder exhibir
todo de manera apropiada. L et's toman una referencia
a las opciones como una matriz de sus nodos hijos usando el método Get children. Y en una función pública
llamada Opciones de visualización, aceptando una línea de
diálogo como una cadena y una matriz de cadenas para las opciones entre las que elija el
jugador. Al igual que la función de línea de visualización, asignaremos la
matriz de líneas para sea solo la línea única
que se pasó como parámetro y la
configuraremos dentro corchetes y estableceremos
la línea actual en cero. Al mostrar las opciones de diálogo, quiero que el
nombre del orador esté oculto, así que lo configuraré para que
sea una cadena vacía. Entonces podemos decirle al
cuadro de diálogo que lo abra si
no lo está ya y comenzar a
escribir la siguiente línea. Donde esto
difiere de mostrar una simple línea de
diálogo, sin embargo, es mostrar los botones de
opción, lo que no quiero que suceda
hasta después de que la línea
haya terminado de escribir. Para eso, necesitaremos
otra señal, emitida por la siguiente función
de línea. L et's lo llaman terminó de escribir. Y esperar esta señal
después de la siguiente llamada de línea. También tendremos que definir esta señal en la
parte superior del guión. Una vez que
se ha completado la escritura, el botón de continuar ya no
es relevante. Por lo que debemos establecer su
propiedad visible en caídas para ocultarla. Luego podemos usar un bucle de cuatro para
iterar a través de la
matriz de botones de opción Pero como necesitamos hacer
coincidir los índices de
la matriz de botones con los
índices de la matriz de cadenas, en su lugar
podemos usar un tipo
diferente de cuatro bucles. Usando el alias I, que en programación se
usa universalmente para índice, seguido de la palabra clave, podemos iterar a través
del tamaño de las matrices El valor de I comenzará
en cero y aumentará uno hasta que alcance el
tamaño de la matriz de botones, en este caso, tres y se detendrá. Ahora podemos usar el valor de i para verificar si es menor que el tamaño de la matriz de
cadenas que se pasó como parámetro
a esta función. En caso de que el diálogo tenga menos del
número máximo de opciones. Si esto es cierto, entonces podemos establecer la propiedad text
del botón en index al
valor de cadena del mismo índice, y también establecer el
botón para que sea visible. Si el índice del botón es
mayor que el número de opciones, entonces el botón
no debería ser visible. Por último, podemos decirle
al botón superior que
tome el foco para que se pueda
acceder a él con un controlador. Para que esto funcione
sin problemas con nuestras otras funciones de
visualización de diálogo, tendremos que alternar
la visibilidad
del botón de continuación
y los botones de opción al escribir líneas de diálogo. También moveré la línea diciéndole al botón de continuación que tome el
foco para estar aquí también. Con todo
visualizado correctamente, solo es cuestión de
contar el guión del evento, qué opción seleccionó el
jugador. El tipo de retorno de esta
función será un entero. El índice del botón que presionó
el jugador, que coincide con el índice de
la elección que seleccionó. Cada uno de nuestros botones, con un
clic, llamará a una función. Vamos a llamarlo en opción presionada, con un
parámetro entero llamado index. Esta función, al igual que
presionar el botón de continuación, puede cerrar el
cuadro de diálogo y emitir una señal. Llamemos a la señal seleccionada, y pasemos el índice a través de la señal
como argumento. En la parte superior del script, podemos darle una definición a esta
señal, y esta vez, también darle a la señal un
argumento entero llamado choice. La
función de opciones de visualización ahora puede devolver un peso seleccionado, lo
que hará que espere hasta que el jugador presione
uno de los botones, luego reciba el índice
entero
del botón que se
presionó y lo devuelva. Lo último que hay que hacer es conectar las
señales pulsadas del botón a esta función. Asegúrate de que tu script se haya guardado para que el motor pueda
encontrar esta nueva función. Seleccionando cada uno de los botones, conectando la señal presionada, seleccione el
nodo del cuadro de diálogo de la lista. Ignora el método de
receptor sugerido y haga clic en el botón de selección. Esto presenta una lista
de funciones en el script de diálogo
cuyos parámetros coinciden con los argumentos de las señales. Dado que la señal presionada no
tiene argumentos, solo las funciones sin
parámetros son compatibles. Haga clic en el botón
Métodos compatibles solo para ver una lista completa de funciones y
seleccionar las opciones presionadas. Para solucionar el problema de compatibilidad, necesitamos agregar nuestros propios argumentos a la señal en la sección
avanzada. Usando el menú desplegable, podemos seleccionar cualquier
tipo incorporado para el argumento. El que queremos
usar es un entero. Al agregar un
argumento entero a la señal, podemos establecer su valor como el índice de
matriz del botón. Botón de opción cero es índice
cero. Haga clic y conéctese. Entonces podemos repetir este proceso con el resto de
los botones de opción, cambiando el valor del argumento para que
cada uno coincida con su
índice en la matriz. El argumento se pasará ahora a la función
pulsada de opción on, emitida por la
señal seleccionada y devuelta por la
función display options de vuelta al
script del evento, que lo llamó. Para probar las opciones de
diálogo, modifiquemos el guión del evento de
diálogo Maj Similar a mostrar una
sola línea de diálogo. Podemos esperar em diálogo Opciones de
visualización, proporcionando una
línea corta de diálogo, seguido de una variedad de opciones. Esta sentencia devuelve
un entero entre cero y el número de opciones
en la matriz exclusivamente. Asignando el
entero devuelto a una variable, entonces
podemos ramificar nuestro
diálogo en función de su valor Puede usar una
declaración if para esto, pero encuentro declaraciones de coincidencia mucho más limpias para este propósito. La palabra clave match funciona manera similar a cambiar
en otros idiomas. En el bloque de código que sigue a
la sentencia match, podemos proporcionar una opción
seguida de dos puntos, luego dentro de ese bloque de código, proceder con lo que
sucederá en ese caso. Y brindar diferentes
casos para cada una de nuestras opciones de diálogo.
Vamos a probarlo. Tengo la velocidad de escritura de texto establecida al mínimo para probar
el botón continuar. Si hablamos con el
mago, dirán una línea de diálogo,
que podemos saltarnos. Después de saltar, se nos
presentan tres opciones, que han agarrado el foco, y el botón continuar ya no
está disponible Seleccionando cualquiera de las opciones, el diálogo continúa en
base a la selección que. Si lo volvemos a hacer, podemos
seleccionar una opción diferente. El mago dice
algo diferente. Podemos simplificar aún más este
script
reemplazando la declaración
de
variable la sentencia match. Ahora tenemos opciones de diálogo para que el jugador elija,
lo que lleva a ramificar árboles de
diálogo En la siguiente lección,
podemos permitir que el jugador progrese a través del
juego durante estos eventos. Te veré en la siguiente lección.
7. Banderas: Hola, amigos. En
la lección anterior, permitimos al jugador
elegir de una lista de opciones y usamos su selección para
crear un diálogo de ramificación En esta lección, usaremos marcadores de
progresión para
cambiar la forma en que se desarrollan los eventos. Empecemos por hacer que el diálogo de un
NPC cambie cada vez que el jugador
interactúe con En cualquier script que estés usando
para tus juegos guardar el archivo, en este proyecto, estamos usando un recurso personalizado
llamado progress. Podemos agregar una variable exportada para rastrear cuántas veces el jugador ha interactuado
con el maj como un entero, que naturalmente
por defecto tendrá un valor de cero En mi proyecto, se ha eliminado el guardado
y la carga
real de archivos. Ten en cuenta que
mis demostraciones siempre
comenzarán con
los valores predeterminados. Para obtener más información sobre cómo guardar información de
progreso
y recursos personalizados, consulte el curso anterior esta serie, Fundamentos de
desarrollo de juegos. En el script Mage Dialogue, podemos iniciar nuestra función run
event haciendo coincidir
primero el
valor de esta variable. Entonces en base al número de veces que el jugador ha
hablado con el Mago, podemos proporcionar diferentes
líneas de diálogo. Tendría sentido
que si el jugador nunca
ha hablado con el Mago, que el primero pueda comenzar
con una introducción. Entonces podemos acceder a
la misma variable e incrementar su valor en uno Y la próxima vez que el jugador
hable con el mago, dirán
algo diferente y también aumentarán
el valor en uno. Al agregar una
opción predeterminada, en el script de Gado, esto se identifica con un
guión bajo en lugar de un valor Podemos proporcionar una
línea de diálogo repetida para después de que el jugador haya agotado
todas las opciones anteriores. La tercera vez,
hablando con el mago, y cada vez después de eso, produciremos esta
línea de diálogo. Vamos a probarlo. La primera vez que hablamos con el mago,
ellos se presentan. La segunda vez pasan
a ser un anfitrión hospitalario. La tercera vez y
cada vez después de eso, simplemente nos
dirán que
están demasiado ocupados para hablar ahora mismo. Alternativamente, en lugar de
tener diálogo repetido, podríamos esta interacción después de que se
haya agotado el diálogo, por lo que este PNJ
ya no será interactable También podemos crear ciclos
de repetición de diálogo
restableciendo el valor a un número menor después de
la última opción Entonces ahora el made dirá
algo diferente cada vez que repita las mismas tres
líneas en orden secuencial. En lugar de crear una
variable separada para cada MPC, es posible que desee considerar el
uso de una matriz de enteros Tendremos que inicializar esta matriz para que contenga
un cero para cada MPC Como tengo tres NPCs, agregaré tres
ceros a la matriz Entonces a cada MPC de tu
juego se le puede asignar un número a partir de cero
utilizado para indexar la matriz Podemos hacer este error más fácil
y menos propenso usando una enumeración,
una lista numerada Me gusta mantener todas
mis enumeraciones de
mi proyecto en un solo
script llamado enums Empezando por
darle un nombre de clase Enums. No necesita
heredar ninguna de las propiedades
del nodo ya que no
se adjuntará a una El único contenido de
este script será declarar enumeraciones para ser
utilizadas a lo largo del proyecto Nuestro primer número será una lista
de todos los PNJ en el juego,
noche, Mago y Rogue La convención para Enums es
usar la caja superior de serpiente, a veces denominada caja de serpiente
gritando El
script de diálogo Mage ahora puede acceder a la matriz e indexarla
con la enumeración. F. Estas son prácticas comunes
para el diálogo de NPC en los juegos, pero en realidad no permiten que el jugador
avance a través del juego Usemos la puerta como
ejemplo de progreso y que el jugador pueda abrir la puerta durante un evento de
interacción, pero solo si
conoce la contraseña. conocimiento de la
contraseña debe ser dado al
personaje del jugador por el mago a través de un evento de
diálogo separado antes de que se le permita usarla
para abrir la puerta. En el recurso progress, podemos agregar una variable
booleana exportada para saber si el
jugador conoce o no la contraseña, que naturalmente
por defecto será Las variables booleanas
utilizadas para controlar la progresión
del juego se
conocen comúnmente como banderas Al hablar con el mago, el personaje
tendrá la opción pedir ver al prisionero. Al seleccionar esta opción, el mayor le dirá al
jugador la contraseña. En ese momento podemos establecer la variable en el recurso
progress en true, ya que el personaje del jugador
ahora conoce la contraseña. Adjuntando un guión a la puerta, Podemos agregar una
variable exportada que indique si la puerta está actualmente abierta y agregar tres funciones públicas, verificando si la puerta está abierta, abriendo la puerta, y
cerrando la puerta. Devolviendo un booleano. Simplemente devolveremos el valor de
la variable is open, para que otros scripts puedan
obtener fácilmente su valor, pero no establecerlo. Aplicando encapsulación. También declararé
una variable para mantener la posición y de la puerta
cuando esté cerrada como flotador. Y establecer su valor durante
la función ready para que sea su posición actual y o su posición actual y
más 4 metros, base en el valor de es abierto. Cada una de estas funciones
puede establecer la variable is open y luego llamar una función privada
para mover la puerta. Para abrir una puerta,
moveré su posición y hacia abajo 4 metros y para cerrarla, restableceré su posición de nuevo
al valor cerrado. Con una variable Tween. Después de verificar para
asegurarse de que la preadolescentes aún
no existe y no se está ejecutando
actualmente,
cree una nueva preadolescentes. Quiero que el nodo de la puerta permanezca interactable mientras
la puerta esté abierta Yo permaneceré en
la misma posición, y en cambio voy a twe
apenas me las puertas. Abriendo esta escena, ignorando la advertencia ya que
no estoy haciendo ninguna edición Podemos ver que el nodo de malla de esta puerta es n Wall Half. Voy a usar eso como el
nodo que está siendo tweed y entre su
posición y valor Dado que la posición
es la propiedad, podemos acceder a la propiedad y de la
estructura del vector tres con dos puntos en la ruta de propiedad para movernos a la nueva posición durante una
duración de 1 segundo. Devolver la señal de tween
terminada a través de
las llamadas a la función en caso cualquier otro script
quiera esperarla. Esto es un poco exagerado
para esta demostración,
pero este guión ahora es lo suficientemente
flexible como para trabajar
tanto con la apertura como con el cierre puertas
similares en
cualquier parte de mi juego En el script de
eventos de interacción de puertas, necesitaremos una referencia
al nodo raíz de puertas. Por simplicidad,
solo usaré get parent. Primero podemos verificar si la
puerta está abierta actualmente. En este caso, podemos terminar el evento para
devolver el control al jugador, luego decirle a la puerta que cierre y regrese para evitar que ejecute
más de este guión
. El jugador no tendrá que
esperar mientras
se cierra la puerta y puede seguir jugando. Si la puerta está
cerrada, entonces podemos verificar si el jugador conoce
la contraseña o no. Si el jugador aún no
conoce la contraseña. Podemos presentar un
diálogo sencillo sobre la puerta que se cierra herméticamente
y se termina el evento. Pero si el jugador sí
conoce la contraseña, haré que los bárbaros digan la contraseña en
línea de diálogo,
terminen el evento y le digan a
la puerta que abra Me gustaría
evitar que el jugador interactúe
con la puerta mientras se está abriendo o cerrando en
caso de que el botón coincida. En ambos casos, estableceré la capa de colisión del nodo de
interacción en cero, evitando que la interacción
rec la detecte. Luego agregue un peso
y vuelva a colocarlo a su valor original después de que la puerta haya terminado de
abrirse o cerrarse. Podemos ver el valor
cubriendo el mouse
sobre la máscara de bits. Cada capa está representada
por un solo bit, ya sea un cero o
uno en memoria. Y cada bit está numerado a
partir de cero. La capa cinco es el bit número cuatro. Su valor representado
como un entero es entonces dos a la potencia
de cuatro, que es 16. Así podemos reactivar
este colisionador estableciendo su
capa de colisión de nuevo Si usa múltiples capas de
colisión, sumar sus
valores de bit juntos
generará el
valor entero de la máscara de bits Cualquier entero se puede usar como
máscara de bits de esta manera y es una
forma extremadamente eficiente de almacenar hasta 32 banderas booleanas
dentro de un La puerta necesita
ser ajustada usando en listo. Vamos a probarlo. Al intentar interactuar primero
con la puerta, la puerta se cierra herméticamente. Pero después de hablar con el mago y adquirir conocimiento
de la contraseña, interactuar de nuevo con la puerta, la interacción se desarrolla de
manera diferente y la puerta se abre. Una vez que la puerta esté
completamente abierta, podremos interactuar con
ella nuevamente para cerrarla. Ahora tenemos
banderas de progreso que permiten al jugador progresar a través del juego usando eventos. En la siguiente lección,
cambiaremos lo que está viendo
la cámara
durante los eventos. Te veré en la siguiente lección.
8. Cámara: Hola, amigos. En
la lección anterior, permitimos que el jugador
progresara en el juego configurando y leyendo
banderas durante los eventos. En esta lección, agregaremos una cámara cinematográfica al sistema de gestión de
eventos Comencemos en la escena del
juego agregando una cámara tres nodos D
al administrador de eventos. Y establecer una referencia a ella en
el guión del gestor de eventos. Después en el nivel sn, usando el
evento de diálogo maje como ejemplo, podemos agregar otra
cámara tres nodos D como un niño al evento de
interacción. Luego mueve la cámara y usa el
alternador de vista previa de la cámara para posicionar o rotar la cámara hacia
donde creemos que quedará bien como perspectiva
para nuestro evento de diálogo. Una vez que estés satisfecho
con cómo se ve, cambia el tipo del nodo a Marcador tres D y cámbiale el nombre a algo
más apropiado. Conservando sus propiedades
transformadas de posición y rotación
dentro de la escena. Ahora podemos usar este
marcador para posicionar la cámara cinematográfica
durante el evento de diálogo Añadiendo un guión a
la cámara cinematográfica, lo
pondré en la carpeta de
eventos Necesitaremos una función pública para mover la cámara a un marcador, configurando la posición
y rotación de la cámara para que coincida con
la del marcador y haciendo de
esta la cámara actual. Pero dado que las posiciones
y rotaciones de los niños son relativas
a sus padres, necesitaremos usar la posición
global y rotación
global para
asegurarnos de que estamos obteniendo
los valores correctos Después en el guión del evento de
diálogo Maj, podemos tomar una referencia a este nodo marcador y decirle al administrador de eventos que mueva la cámara cinematográfica hacia Cuando
termine el evento, necesitaremos que el administrador del juego
vuelva a cambiar a la cámara del jugador. En el guión del administrador del juego, necesitaremos una referencia a la cámara principal del jugador para
que cuando terminen los eventos, podamos hacer que la cámara del jugador sea la
cámara actual antes de permitir que el
jugador comience a jugar nuevamente. Vamos a probarlo. Al
hablar con el mago, la cámara cinematográfica se mueve hacia
el marcador y se hace cargo Entonces cuando termina el evento, la cámara del jugador
reanuda el control. También podemos desvanecer la transición entre cámaras con bastante facilidad. Añadiendo una función al script del administrador de
eventos, llamémoslo fade to marker, aceptando Marcador tres D y devolviendo una señal. Podemos esperar fundido a negro, luego enviar el marcador a
la cámara cinematográfica Luego regresa fade a c. El administrador del juego también
puede desvanecerse dentro
y fuera al cambiar de
nuevo a la cámara del jugador. Pero solo tendría
sentido hacer esto si el evento estuviera usando
la cámara cinematográfica También podemos hacer que este comportamiento opcional agregando un parámetro booleano
opcional a la función y solo usar el fade si lo solicita
el evento específicamente Añadiendo true a la llamada a la función de
evento final, y esperando que Fay marque
al inicio del script La cámara ahora se desvanece
dentro y fuera a medida que cambia la perspectiva al
inicio y al final del evento Si sus eventos tienen
más de un marcador, es posible que desee
ordenarlos en un nodo padre. Vamos a llamarlo marcadores de cámara. Y en el guión del evento, agarra una referencia a él como
una variedad de sus hijos. El guión del evento puede solicitar a la cámara que se mueva al marcador de
cámara cero, uno, dos, et c, más
como un set de filmación. Pero, ¿y si queremos que
la cámara se mueva? Agreguemos algunas funciones más al guión de
la cámara, dirección
panorámica, para mover la cámara usando
un vector y panorámica a marcador para mover gradualmente la cámara directamente a
una ubicación específica. Ambos aceptarán una duración de tiempo para el pan y devolverán una señal para decir el evento cuando estén terminados en caso de
que queramos esperarlo. Para cambiar
algo gradualmente con el tiempo, necesitaremos una variable de preadolescentes Ambas funciones se pueden simplificar en una función
privada, llamémosla cámara de preadolescentes, aceptando el destino
objetivo, la duración del tiempo y
devolviendo la misma señal Como pan a marcador ya
conoce su destino objetivo, simplemente
pasamos esa información a la función de
cámara de preadolescentes, accediendo a la
posición global del marcador Y la
función de dirección panorámica puede calcular su destino objetivo
agregando la dirección a su posición global
actual. Después de verificar si la preadolescente ya existe y se está ejecutando, si es así, mátala, luego
crea una nueva Entonces podemos interponer la posición
global de las cámaras para que sea el destino objetivo durante
la duración solicitada En la función de pan a marcador, también tendría
sentido hacer coincidir la rotación de los marcadores así
como la posición, pero tal vez no siempre. Vamos a agregar un
parámetro booleano opcional para permitir
este comportamiento Podríamos duplicar la función
de cámara de preadolescentes para agregar otra con rotación, pero preferiría
agregar la rotación
en el parámetro booleano
a esta función,
dando a la rotación un valor
predeterminado de Si el evento quiere que la cámara coincida con la rotación de los marcadores, Luego también interpelar la rotación global de la
cámara para que
coincida con la rotación del objetivo a lo largo de la duración Por defecto, múltiples preadolescentes
sucederán en secuencia, pero queremos savia
simultáneamente Podemos agregar otra llamada de función aquí paralela para lograr esto. Si cambiamos estos tipos de
argumentos de un marcador tres D a un nodo
genérico tres D, entonces cualquier nodo tres D
puede usarse como marcador, incluyendo la cámara del jugador. También tendrán que
configurar esta como la cámara activa si no
lo es ya. En el script del administrador de eventos, también
podemos cambiar este
Marcador tres tipo D a un nodo tres D. Agarrando una referencia al nodo de la cámara del jugador lo
marcará como privado, por lo que otros guiones no lo verán Luego podemos agregar una
función que mueva la cámara cinematográfica a la posición de la cámara del
jugador En el guión de diálogo Mage. En lugar de usar el Fade, intentemos ajustar
la cámara cinematográfica a la posición de la
cámara del jugador
y desplazarla
al marcador durante nuestro evento antes de la
primera línea de diálogo Luego, desplaza la cámara hacia arriba y vuelve a
desvanecerse hacia la cámara del
jugador
al final. Vamos a probarlo. Este diálogo ahora
se parece más a una escena cortada con la
cámara moviéndose. Pero podemos llevar
esto aún más lejos creando pistas de cámara que guiarán a
la cámara alrededor la escena en un movimiento de
barrido suave. Comience agregando un nodo D de
ruta tres
al nodo de evento de interacción. Este nodo tiene una propiedad, una curva tres recursos D. Al hacer clic sobre él para
expandirlo, contiene una matriz de puntos. Añadiendo un punto, cada punto contiene un vector de
tres posiciones. Comenzando con el primer punto en la ubicación original de los marcadores, podemos agregar más
puntos a la matriz. Para mover la cámara
por las puertas, Luego a la ventana de los guardias
hacia la celda de la prisión Las otras propiedades de punto son
anclajes que agregan peso
al cálculo de puntos
antes y después de ellos
a lo largo de la curva El primer punto sólo
tiene un ancla out, el último punto sólo
tiene un in ancla, pero cada punto
intermedio tiene ambos. Ajustar estos anclajes
suavizará la curva siguiendo una fórmula de curva de
bezier. Ahora que tenemos un camino que nos
gustaría que siguiera la cámara, necesitamos agregar otro
nodo a la ruta. El camino sigue tres nodos D. La segunda propiedad
del nodo de seguimiento de ruta, la relación de progreso lo moverá a
lo largo de la ruta
en un porcentaje. Añadiendo una cámara tres nodos D
al nodo de seguimiento de ruta y dando su rotación original
mirando hacia el mago. Luego podemos hacer clic en
la palanca de vista previa para ver desde la perspectiva de la
cámara. Después ajusta el valor de progreso y observa la cámara
sep a través de la escena. Ya podemos eliminar la
cámara tres nodos D. Para hacer esto en nuestros scripts, solo
necesitamos
tomar una referencia
al nodo path follow
en el script de evento. Voy a romper
el diálogo en líneas
separadas para sincronizar
mejor con los movimientos de la cámara También podemos usar esto como
marcador para posicionar la cámara si queremos antes de
iniciar el movimiento. Entonces podemos decirle a la
cámara que siga un camino, pasando el
nodo path follow como argumento, junto con la duración del tiempo. Definamos esta función
en el script de la cámara. Aceptar un camino a seguir y una duración de
tiempo como parámetros. Lo primero que
tendremos que hacer es volver a padre la cámara
al nodo de seguimiento de ruta, luego restablecer su posición
y rotación para que coincida con ella. Hacer todas las cosas habituales de tween y devolver la
señal cuando termine Entonces podemos interponer la propiedad
progress
del nodo follow para
alcanzar un valor de uno a lo largo de
la duración del tiempo Y hacer de esta la cámara
actual. Por último, el
administrador del juego puede volver a formar la cámara cinematográfica con el administrador del evento mientras termina
el evento si es necesario L et's pruébalo. Después de
mencionar al preso, la cámara barre por la escena para
mirarlos por la ventana Si quieres restringir
la forma en que gira la cámara
siguiendo el camino, es fácil
limitarla a que solo gire alrededor del eje y
o no gire en absoluto. Ahora tenemos una
cámara cinematográfica que puede tomar nuestros sencillos eventos de diálogo y
convertirlos en escenas cortadas En la siguiente lección, también
agregaremos animaciones de personajes. Te veré en la siguiente lección.
9. Animación: Hola, amigos. En
la lección anterior, agregamos una cámara cinematográfica
al sistema de eventos Y esta lección animará a los personajes
durante nuestros eventos Empecemos en una escena de
personajes. Al seleccionar el
nodo del árbol de animación, el panel del árbol se abre en la parte inferior
del editor, Mostrando la máquina de
estado que controla la mecánica de
movimiento de los personajes. Para obtener más información
sobre los conceptos básicos de la animación de personajes
y las máquinas estatales, consulte la introducción al curso de desarrollo de juegos de tres
D. Para evitar confundir
las redes enredadas de transiciones de estado, podemos mantener diferentes tipos de animaciones separadas en
diferentes máquinas de estado Al hacer clic con el botón derecho en el espacio vacío, agreguemos una nueva
máquina de estado a esta. Por falta de un nombre mejor, lo llamaré misceláneo. Usando la herramienta Conectar, agregue conexiones desde la locomoción a la nueva
máquina de estado y vuelva de nuevo. Usando la herramienta de selección, seleccione la transición de locomoción a la
nueva máquina de estado Amplíe la sección de avance y cambie el modo
de avance de automático a habilitado. Esto nos permitirá activar
las animaciones a través del script en lugar de esperar que
el árbol
de animación maneje automáticamente la transición, como lo que está sucediendo con
la mecánica de movimiento. Seleccionar la otra transición, expandir la sección del interruptor y cambiar su
modo de conmutación a al final, permitiendo que cualquiera de las
animaciones dentro la nueva máquina de estado termine antes de regresar
a la locomoción Al seleccionar la nueva máquina de
estado, cambie el
tipo de máquina de estado de raíz a agrupada. La mecánica de movimiento es actualmente la máquina de
estado raíz, y esta nueva
máquina de estado contendrá animaciones
similares que se
agruparán para ayudar a
mantener las cosas organizadas. Después haga clic en el icono de Lápiz para editar esta nueva máquina de estado. Podemos volver a la raíz de
la máquina de estado usando los botones de miga de pan en la parte superior del panel del árbol de
animación En esta
máquina de estados, podemos agregar cualquier animación que inicie y termine con
la pose inactiva, que están pensadas para ser
reproducidas una vez y no loop. En este paquete de activos, las animaciones de animar, interactuar y recoger se
ajustan a esta descripción Para que la máquina de
estado funcione como se esperaba, el número de transiciones
desde el inicio debe coincidir con el número de transiciones que ingresan a
la máquina de estado. Asimismo, el número
de transiciones que salen la máquina de estado debe coincidir con el número de transiciones
que conducen al estado final Dado que solo hay
una transición dentro y fuera de
la máquina de estado, solo puede
haber una transición conecte de principio a fin. Necesitamos un
estado intermedio en el medio, el estado que
inicia y termina todas estas animaciones, la pose ociosa. Desafortunadamente, este asset pack no contiene una pose inactiva, pero podemos hacer una fácilmente. Cambie al panel de animación en la parte inferior del editor. Y selecciona la
animación inactiva en el menú desplegable. Haga clic en el
botón de animación junto
al menú desplegable, luego
seleccione duplicar Cambie el nombre de la nueva pose de inactividad de
animación. Cambia la duración
de la
animación de pose inactiva a cero y
desactiva el bucle De vuelta en el panel del
árbol de animación, dentro de la máquina de
estado miscelánea, podemos agregar dos copias de
la animación pose inactiva. L et los nombra Idle Post
start y Idle Pose end. Después conéctate de inicio a pose
inactiva y luego al
otro estado de ahí. Y cada uno de estos a
la segunda pose ociosa, y finalmente, al estado final. Seleccionando cada una de las transiciones
desde el inicio de pose inactiva, cambie su
modo avanzado a habilitado. Y las transiciones al extremo de
pose inactiva pueden cambiar al final. Ahora el número de
transiciones dentro y fuera de la máquina de estado
coincide con el número de transiciones de
inicio y fin a fin. No hay posibilidad de ambigüedad para que el
árbol de animación lo navegue sin problemas Podemos previsualizar cómo se
ven
estas animaciones haciendo clic en el botón de
reproducción junto a ellas. Y podemos agregar una
corta duración de fundido
cruzado a las transiciones dentro y fuera de la máquina de
estado para mezclarlas
mejor con
los estados de locomoción Cuando estés satisfecho
con la máquina de estado, podemos guardarla como un recurso
dentro del proyecto. Después de crear las animaciones de
pose inactiva para
los otros personajes, esta máquina de estado se
puede cargar en sus nodos de árbol de animación ya que todos tienen
las mismas animaciones. En el guión de caracteres, podemos agregar una función pública para activar la
transición a cualquiera de estas animaciones simplemente pasando el nombre de la
animación como una cadena. Solo necesitamos decirle a la reproducción de la
máquina de estado que viaje a la animación
agregando el nombre de la máquina de estado agrupada que la
contiene al frente, junto con un separador. Pero tendremos que
restringir manualmente solo permitiendo que
esto suceda desde el estado de locomoción comprobando primero las
máquinas de estado nodo actual Si el nodo actual no
es locomoción, debemos ignorar esta solicitud Esto evitará que se inicien estas animaciones
mientras se encuentra en salto medio. También es posible que no queramos que
el personaje
pueda moverse mientras se reproducen estas
animaciones. Vamos a agregar un parámetro
booleano opcional llamado locked con un valor
predeterminado de true Y también declarar una variable
privada para el script indicando si el carácter se mueve
simultáneamente o no Añadiendo un setter a esta variable
después de establecer su valor, Si el carácter no puede moverse, también
debemos establecer el
valor de dirección de entrada a cero para detener el carácter
si ya se están moviendo Entonces en cualquier función
que se mueva o salte, podemos agregar una
sentencia condicional comprobando si el personaje puede moverse
antes de permitir que suceda. Cuando se le dice que realice
una animación, si la animación bloquea el movimiento, entonces podemos establecer la variable
can move en
false y
volver a establecerla en true después de que termine la
animación. Pero no podemos simplemente esperar la señal de
animación terminada, ya que se emitirá cuando termine
la animación actual, que está inactiva, no la
que queremos esperar. Colocando el comando wait dentro un bucle while y simplemente
continuando el bucle, podemos esperar cada señal de
animación terminada repetidamente hasta que se emita la específica
que queremos. Mantener el control o comando
y hacer clic en la señal. Podemos ver que pasa un argumento del
nombre de la animación que acaba de terminar. O. Solo necesitamos comparar este valor
con el nombre de la animación, que cuando se recibe,
ahora romperá el bucle de espera y establecerá la variable can
move de nuevo a true. Por último, para usar esto como parte del sistema de
gestión de eventos, deberíamos tener una señal de
retorno, si acaso
queremos esperarla. Llamemos a esta señal de
animación terminada. Podemos emitir y
devolver la señal
si la animación
fue cancelada y darle un
parámetro booleano para saber si la
solicitud de animación fue exitosa
o no Pasar falso es el argumento. Y al final de la
función con true. Definir la señal y su parámetro en la
parte superior del script. Dado que nuestro gestor de eventos ya tiene una referencia
al personaje del jugador, decirle que realicen estas
animaciones ahora es trivial En el guión de
interacción de la puerta celular, esperemos e interactuemos animación antes de que ocurra cualquier
diálogo. En el guión de diálogo Maj, necesitaremos una referencia
al personaje de Maj para
poder solicitarles
animaciones, lo cual se puede hacer fácilmente usando add on ready
y get parent, ya que esta nota de interacción
es infancia para el Si quieres incluir
varios caracteres, simplemente exporta una variable para cada uno que se incluya
en el diálogo. Voy a hacer que el maga se anime mientras hablo excluyendo
la palabra clave de espera, pero finge que la
animación está realmente enojada Tenga en cuenta que también podemos
dar a los personajes otros comandos
como start jump o dirección de cara.
Vamos a probarlo. Al hablar con el mago, se mueven furiosamente mientras le gritan al personaje del jugador
en diálogo Si interactuamos con la puerta, el personaje del jugador
se acercará y la
tocará antes de iniciar
el resto del evento. Ahora tenemos la capacidad de
animar personajes
durante nuestros eventos En la siguiente lección, moveremos a
los personajes a. Te veré en la siguiente lección.
10. Dirección: Hola, amigos. En
la lección anterior, agregamos animaciones de personajes
al sistema de eventos. En esta lección, les diremos a los personajes que caminen
y corran alrededor de dos. Vamos a configurar una escena básica de corte. Al hablar con el mago, hagamos que caminen de
regreso a la pared, agarren algo de la repisa, regresen al jugador
y se lo entreguen. Como hicimos con la cámara, podemos agregar marcador tres nodos D que le dicen al personaje
dónde moverse. Al igual que las direcciones escénicas. Podemos agregar uno como
hijo del mago para copiar
fácilmente su posición exacta
actual. Después duplicarlo y mover el nuevo para que quede por encima de
las repisas en la pared. Asegurándose de dejar
suficiente espacio para que el colisionador del personaje
no choque con la pared antes de
llegar al destino Si tiene múltiples
marcadores en un evento, sería útil que se
ordenaran bajo un nodo padre. Al hacer clic y
arrastrarlos para volver a ser reparentados. Pero si el personaje
anda por ahí, ya que todos estos
nodos son hijos del nodo personaje,
todos se moverán a. Podemos seleccionar los
nodos padre que tienen nuestros marcadores, expandir la sección de transformación y hacer clic en el botón de alternancia de nivel superior, lo que evitará que
las propiedades de transformación se hereden. Los marcadores
permanecerán estacionarios mientras el hecho camina alrededor. Luego en el script del evento, podemos tomar una referencia a este nodo como una matriz
de sus hijos. Después de una línea de diálogo, podemos decirle al mago que camine
al marcador de personaje uno, interactúe, luego regrese al marcador de
carácter
cero e interactúe nuevo antes de mostrar
otra línea de diálogo. En el guión del personaje,
podemos agregar la función que le dice al jugador que se mueva a un marcador. Aceptando un tres D como marcador, y una distancia permisible
al destino como
flotador para los parámetros Esto permitirá que la función termine cuando el personaje se acerque lo suficiente al marcador sin tener que pararse
directamente encima del mismo. Vamos a darle un
valor predeterminado de un cuarto de metro. Después devuelva una señal
cuando esté terminada. Vamos a agregar una señal
llamada destino alcanzado luego emitirla y devolverla al
final de la función. Restar la posición global
actual del personaje
del destino
nos dará un vector apuntando a él, un vector con una
dirección y una distancia Nuestros controles de caracteres asumen
una longitud de vector de uno, ya que eso es lo que proporciona
el singleton de entrada Al usar esta dirección
para mover un carácter, tendremos que
normalizarlo primero, estableciendo la
longitud del vector en uno. Simplemente estableciendo la variable de
dirección, el proceso de física moverá
entonces al personaje. Si envolvemos todo
esto en un bucle wile, podemos seguir ejecutando este
código mientras el carácter esté más lejos del destino
que la distancia permitida A la espera del siguiente marco de física Este código se ejecutará junto con el proceso de física para mover al personaje de donde
están a donde van. Cuando se alcanza el destino, podemos establecer su
dirección en el vector 30 para detener su movimiento, pero el personaje seguirá desacelerando hacia adelante desde aquí Si queremos que el personaje se detenga con
mayor precisión en el marcador, deberá comenzar a
desacelerar antes de alcanzarlo Entonces podemos
dividir esto en dos fases antes y después del punto donde
el personaje comienza a
desacelerarse, llamada distancia de parada Podemos calcular la distancia de
parada
tomando su velocidad actual
x z,
promediándola con una
velocidad de cero, que puede simplificarse para
dividirla por dos, luego dividirla también
por su desaceleración La distancia de parada será mayor cuanto más rápido se mueva el
personaje, y también dependerá de
la tasa de desaceleración Hasta que el personaje alcance
la distancia de parada, acelerarán
hasta su máxima velocidad. Al llegar a la distancia de
parada, comenzarán a
desacelerarse y llegarán a una parada completa más o menos directamente en
su destino Si la distancia permitida se logra antes de la distancia de
parada, entonces el personaje aún
se detendrá Todo esto se puede hacer usando una declaración turn rey
en una línea. Siempre y cuando el
personaje jugador interactúe con el mago desde el
frente, esto funciona bien Pero si el
personaje jugador se interpone en el camino de donde quiere caminar el
mago, esto puede hacer que el mago
no pueda llegar a
su destino. Si bien la navegación alrededor un entorno estático
es bastante simple, encontrar rutas
dinámicas alrededor obstáculos en
movimiento es un problema
difícil de resolver. Muchos juegos más antiguos a menudo tenían personajes paseándose
entre sí o podían ser bloqueados por un tiempo limitado
y luego salían a su
destino como último recurso. Ninguno de estos se ve muy bien. La mayoría de los juegos modernos, entre ellos AA, optarán por que
sus escenas de corte operen en un
entorno completamente controlado y eliminarán cualquier posibilidad
de obstrucción del camino. Para lograrlo,
cualquier escena de corte que evolucione personajes
caminando por ahí comenzará por desvanecerse a negro Entonces cada personaje de la
escena puede ser reposicionado, si es necesario antes de
comenzar la escena Entonces, cuando la escena vuelve a
desvanecerse, cada movimiento es coreografiado
cuidadosamente Podemos agregar otro
marcador de personaje para especificar dónde debe
estar
el personaje del jugador durante esta interacción. Pero con el
nivel superior activado, los marcadores de personajes parecen haberse movido al origen de
la escena, pero aún conservan sus posiciones
globales como antes Esto hace que añadir
más marcadores sea difícil. Desconectemos la alternancia de nivel
superior y editemos la posición de transformación
para obligarla a actualizarla, luego restablecerla a cero. Ahora aparece en la posición
correcta. Agreguemos uno más
y lo llevemos a donde
debería estar parado el bárbaro Estableciendo su rotación para
enfrentar hacia la edad. Después vuelve a encender el nivel superior. En el guión del personaje,
necesitaremos una función que en lugar de wockear
el personaje a un marcador,
simplemente establecerá su posición y
posiblemente
rotará simplemente establecerá su posición y directamente a él Aceptar un nodo tres
D como parámetro y un parámetro opcional para hacer coincidir la rotación y con un valor
predeterminado de true. No necesitamos devolver una señal ya que esto sucederá
instantáneamente Establecer la posición
global del personaje para que coincida y si coincide con
la rotación, también establece la rotación y
de la plataforma para que coincida con eso. Cuando comienza la escena de corte, primero
nos desvanecemos a negro. Luego coloca al personaje
del jugador en el personaje Marcador dos, haciendo coincidir su rotación también, antes de volver a desvanecerse y reanudar el
resto de este evento Ahora, incluso si deliberadamente nos
paramos en el camino de la mayor, la escena cortada se desvanecerá
a negro para corregir esto antes de tocar el evento de una manera más
controlada para evitar posibles problemas. T L et's hacen que la
función de caminar de personajes sea aún más flexible al agregar la opción
para que el personaje se ejecute. Agregar un parámetro booleano llamado running con el valor
predeterminado false Podemos decirle al personaje que se ejecute al inicio de la función y caminar al final de la función si este parámetro
se establece en true. También podemos agregar otra
función que permitirá al personaje seguir un camino con múltiples puntos
en lugar de solo uno. Comenzando con la misma
definición de función que mover a maker, vamos a cambiarle el nombre de la ruta de seguimiento. Cambie el primer parámetro
a path y elimine el tipo. Simplemente asumiremos que es una matriz de nodo tres D
sin forzarlo. Después emitir y devolver la señal de
destino alcanzado. Declarando una nueva variable para el punto actual en el
camino hacia el que nos dirigimos, que comenzará en cero Siempre y cuando este número sea menor que el tamaño de la matriz, deberíamos esperar
a pasar a ese marcador. Y podemos pasar a lo largo la misma distancia permisible
y valores de carrera En la escena de las mazmorras, he seguido adelante y he
colocado un marcador para el bárbaro camine
después de abrir la puerta, y tres marcadores que forman un camino para que el
roge corra Dado que el
nodo de interacción de la puerta no se mueve, tampoco
hay necesidad de preocuparse de que
los marcadores se muevan. La interacción de la puerta celular necesita
entonces una referencia
a estos marcadores, así
como al carácter pícaro Mientras
se abre la puerta, el bárbaro puede apartarse del
camino para marcar cero Entonces el pícaro mostrará gracias
al salir de la celda
de la prisión Voy a añadir más indulgencia de
distancia permisible y tener el Dejaré que el jugador vuelva a
tener el control
tan pronto como termine
con el cuadro de diálogo, para que no tenga que
quedarse inactivos mientras el pícaro corre. Vamos a probarlo. Al interactuar con
la celda, la puerta se abre y el bárbaro
camina hacia un lado Entonces el pícaro dispara
gracias y se escapa. Ahora tenemos personajes capaces caminar y correr durante los eventos. Y la siguiente lección mejorará el diseño modular
de nuestros eventos. Te veré en la siguiente lección.
11. Modularidad: Hola, amigos. En
la lección anterior, tuvimos personajes caminando y
corriendo durante los eventos. En esta lección,
terminaremos con algunas mejoras en
los guiones de eventos. A lo largo de este curso, hemos creado una variedad de eventos
diferentes. Algunos se activan cuando el jugador
entra en un área específica, otros al presionar un botón. Al observar estos dos guiones, podemos comenzar a ver
la similitud de la función run event con
algo así como un guión, dando indicaciones a personajes y cámaras en un set de filmación Te puedes imaginar al
hacer un juego completo. Van
a haber cientos o posiblemente miles
de estos guiones, posiblemente escritos por
varias personas. Queremos que sean tan fáciles de
escribir y editar como sea posible para reducir la cantidad de tiempo
requerido para producirlos, así
como estandarizados
para reducir posibles errores. Comencemos agregando una declaración de nombre de
clase al script del administrador de eventos. Entonces en nuestros scripts de eventos, especificando el tipo
de gestor de eventos, el motor ahora producirá sugerencias de
autocompletado al acceder a variables o funciones dentro del gestor de eventos Una característica útil para reducir errores en cualquier script que lo utilice. A continuación, sería
útil separar
cómo se desencadena un evento
de cómo se ha ejecutado. Vamos a crear un nuevo script
dentro de la carpeta de eventos. Si bien Godot
en realidad no tiene una implementación de
una clase abstracta, todavía
podemos pretender que esta
es una clase abstracta, una que nunca está destinada a ser instanciada de ninguna
manera, Heredado de Aa tres D, y darle un evento de interacción de
nombre de clase. Al mover el
método interact a esta clase, Cualquier script de evento de interacción en el juego puede heredar
del evento de interacción para ocultar
la función de interacción a través de la herencia También podemos limpiar el código de capa de
colisión
llamando a métodos heredados
con nombres apropiados. Como conjunto interactable, pasando verdadero o falso
como argumento Entonces la clase de evento de interacción puede ocultar los detalles de cómo se logra
esto y
estandarizarlo para todos los
eventos interactuables en el juego Establecer la
capa de colisión en 16 si es interactable o bien cero
para volverse Sería una buena
idea
heredar aún más del
evento de interacción para crear una clase común que se
pueda aplicar a cada interacción similar
en tu juego, como tener un
guión para todas las puertas o un guión para todas las
camionetas, Las únicas diferencias entre
sus interacciones similares variables
exportadas o
referencias a otros nodos. Muchos eventos en los juegos solo se desencadenan bajo
ciertas condiciones, y muchos se vuelven irrelevantes
después de que han sucedido una vez Cualquiera de nuestros scripts de
eventos de interacción puede anular
fácilmente el
método de interacción para agregar condiciones, verificando el progreso del jugador en
busca de banderas si es necesario, antes de llamar a la definición
de
superclase de interactuar para iniciar el evento Bien. Establecer la misma
bandera dentro del evento. También podemos hacer que este evento ininteractable para evitar que el mismo evento ocurra dos veces Otra opción popular es usar el método ready para verificar si se
cumplen las condiciones de
este evento y configurarlo para que sea interactable o no cuando se cargue por
primera vez en el Este suele ser el caso en cualquier momento para activar un evento, se
requiere zonificar y volver al
nivel para restablecerlo antes de hablar con un
NBC, Las condiciones para el evento se están verificando solo
cuando se carga por primera vez. Duplicemos el script de eventos de
interacción y también creemos un script de eventos de
proximidad. Cambiar el
nombre de la clase para que coincida. Podemos intercambiar el
método de interacción con el cuerpo ingresado, aceptando el cuerpo como
un parámetro de tres D. Esta colisión
desencadenará el evento, pero la señal ingresada por el cuerpo
no está intrínsecamente conectada En la función ready,
podemos
conectar manualmente la señal
al método invocable También pongamos la
máscara de colisión para detectar al jugador, que es la capa nueve, el bit ocho, dos a la potencia
de ocho es 256. Ahora cualquier script de evento puede heredar del evento
de proximidad y sus
condiciones de activación, así como enmascaramiento de
colisión, se
manejan automáticamente En este proyecto, he puesto a
todos los personajes en la
misma capa de colisión, por lo que cualquiera de ellos
desencadenará eventos de proximidad. Abriendo la configuración del proyecto, Bajo nombres de capa,
tres D física. Agreguemos una
capa separada para los NPC. Entonces en cada escena de NPC, podemos cambiar su
capa de colisión de jugador a NPC y hacer que
ambos se enmascaren entre sí Ahora solo el
personaje del jugador será detectado por eventos de proximidad. Hagamos también
otro tipo de evento, uno que no sea activado
por el jugador en absoluto, sino que se pueda activar
a través de otros scripts. Es
probable que el manager del juego inicie un evento de
introducción la primera
vez que se cargue el juego Un nivel también podría querer
desencadenar eventos cuando
el jugador entra en él, o eventos pueden querer
desencadenar otros eventos. Al crear un nuevo script
en la carpeta de eventos, llamémoslo evento con guión Esta vez
heredará del nodo, ya que no
necesita ningún comportamiento de la clase de nodo Aa tres D. Dado que un evento con guión
no necesita activarse, el único propósito
del script será garantizar que haya
una función de evento de ejecución, y también proporcionar una señal que se
emitirá cuando termine
el evento, cual puede ser emitida
y devuelta Cualquier script que
herede de esta clase ahora puede devolver el evento super dot run
para automatizar este comportamiento Añadiendo una variable
al archivo seguro del jugador, llamémoslo intro
jugado Ablean, que naturalmente
por defecto será Vamos a crear un
evento de introducción que solo se
activará una vez cuando el juego se cargue por
primera vez Por simplicidad,
solo voy a hacer que se desvanezca ya que el
estado actual del destino es negro cuando el
juego se carga por primera vez. Entonces di hola mundo y
ponle la bandera a verdad. Después devuelve el evento Spot Run, que emite y devuelve
la señal terminada Y también dile al
manager del juego que ponga fin al evento. Agregar una nueva nota
a la escena del juego para celebrar el evento con guión El administrador del juego puede obtener una referencia al mismo
usando add on ready. En la función ready. Ya
podemos verificar esta bandera. Entonces inicia el evento de introducción y
espera su señal terminada. Si la bandera se ha establecido true, entonces
se omitirá Corriendo la escena,
el evento intro ps. Si el jugador guarda
y vuelve a cargar el juego, el evento con guión de introducción
no se activará Voy a demostrar por defecto
la variable en el archivo
sa a True Agreguemos otro nodo para
contener un evento secundario, uno que será desencadenado
por un evento primario. Agregar un script a este nodo heredando
del evento con guión Solo dirá evento
secundario,
y devolverá evento Super dot run Cualquier script de evento en el
juego ahora puede esperar ejecutar este evento secundario
y se
ejecutará antes de regresar
al evento que lo llamó. Esto puede ayudar a dividir eventos
extra largos en trozos más grandes, dividir narrativas ramificadas
en scripts separados o reciclar el mismo evento para ser usado Ahora tenemos un sistema
de
gestión de eventos y
diálogo muy completo sistema
de
gestión de eventos y
diálogo que se puede utilizar para crear narrativas complejas
ramificadas, escenas de corte
convincentes y dar al jugador opciones de cómo quiere
progresar en el juego El sistema también está
optimizado para hacer que la
producción de los
scripts de eventos sea bastante simple.
12. ¿Qué sigue?: Bienvenido a mi curso de
inventario y tiendas en Gado. Este curso es una continuación del diálogo y eventos en Gado pero se
puede seguir y aplicar a cualquier proyecto que implique
recoger artículos, agregarlos a un
inventario, dejar caer, usar o equipar artículos de un menú
de inventario y comerciar artículos con un MPC Te invitamos a unirte a
nuestro servidor de discordia para trabajar en este curso
junto a tus compañeros En este curso, cubriremos diferentes métodos para
recoger artículos,
administrar los datos del inventario de los jugadores, mostrar su inventario
en la interfaz de usuario en un menú, permitir que el jugador interactúe con su inventario de diferentes
maneras, e intercambiando artículos con NPC Cuando termines,
tendrás un sistema de
inventario sencillo para tu juego que es fácilmente personalizable en su presentación
y función. También aprenderás habilidades útiles para trabajar con el motor de juego
Gada, organizando y diseñando tus proyectos para que
sean más escalables. Estarás
aprendiendo a codificar con script
GD con todo lo
explicado en detalle Aplicaremos principios de diseño
orientado a objetos en nuestros scripts,
herencia, encapsulación, abstracción y polimorfismo,
para mantenerlos organizados, personalizables y reutilizables
para un proyecto de Todos los archivos del proyecto
también están disponibles en GitHub, si necesitas revisar
el proyecto tal como estaba después de completar
cada lección. Estos videos se grabaron
usando Gdoersion 4.2 0.2. El proyecto comienza con
activos de K Kits, personajes y
paquetes remasterizados de Dungeon hechos por Paquete Basic Guy
hecho por Penzilla, e iconos hechos por Shakahi Todos están disponibles para
descargar gratis en él. También se
incluyen los efectos de sonido realizados por
Valensbyer y están disponibles