¡Combate en Godot! | Thomas Yanuziello | Skillshare
Buscar

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introduccion

      1:44

    • 2.

      Configuración

      0:32

    • 3.

      Lock On

      15:52

    • 4.

      Strafe

      13:47

    • 5.

      Ataque

      20:46

    • 6.

      Arma

      17:20

    • 7.

      Golpe

      15:43

    • 8.

      sobreexponer/sobreexposicion

      14:43

    • 9.

      Bloque

      15:12

    • 10.

      Rodaje

      17:43

    • 11.

      Enemigo

      15:41

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

22

Estudiantes

--

Proyecto

Acerca de esta clase

¡Este curso es una continuación de Inventario y tiendas en Godot!

Haz clic en el enlace de mi sitio web en mi perfil para unirte a nuestro servidor de discord.

En este curso, abordaremos el bloqueo de un objetivo, la locomoción, el ataque, el recibir golpes, esquivar, bloquear, disparar proyectiles y la IA básica del enemigo.

También aprenderás habilidades útiles para trabajar con el motor de juegos Godot y organizar y diseñar tus proyectos para que sean más escalables.  Aprenderás a codificar con GDscript, con todo lo explicado en detalle.  Nuestros scripts estarán escritos para ser altamente personalizables y reutilizables.  Todos los archivos del proyecto también estarán disponibles en GitHub si necesitas revisar el proyecto tal y como estaba después de completar cada lección.  Estos videos se grabaron con Godot versión 4.3.

Este curso será parte de una serie diseñada para enseñar piezas de desarrollo de juegos del tamaño de un bocado que se puedan usar indistintamente entre sí.  Así que cuéntame qué tipos de juegos te interesa aprender a crear y trataré de incluirlos en futuros cursos de esta serie.

Conoce a tu profesor(a)

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Profesor(a)
Level: All Levels

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introduccion: combate y los videojuegos pueden parecer desalentadores y una característica difícil de implementar Este curso te proporcionará todas las herramientas y conocimientos que necesitarás para crear un sistema de combate escalable y dinámico en Gado. Descompondremos el sistema de combate en mecánicas individuales y las combinaremos para crear un sistema robusto de combate de acción que se puede personalizar para satisfacer tus necesidades. Aprenderás a combinar animaciones de combate y movimiento. Sincronice cajas de golpes con animaciones de ataque, implemente marcos oculares en animaciones de esquivar, Bloquear a los enemigos Dispara proyectiles desde un arma arreglada y controla a los enemigos con guiones de IA Si necesitas ayuda, nuestro servidor de discordia está lleno de otros estudiantes y desarrolladores de juegos que pueden responder cualquier duda que puedas tener Haz clic en el enlace del sitio web en mi perfil para unirte. Voy a estar usando un proyecto de inicio hecho en God versión 4.3 que está disponible en mi GitHub usando activos gratuitos de él punto IO. Pero puedes seguir junto con tu propio proyecto usando diferentes activos. Para aprovechar al máximo este curso, necesitarás una escena en tu proyecto con un personaje que el jugador pueda controlar y al menos un enemigo. También es posible que desee tener un sistema de inventario y equipo capaz de equipar a los personajes con un arma y un escudo Para más información sobre estos temas, consulta mi curso anterior. El combate no tiene que ser una batalla cuesta arriba. Dibujemos nuestras armas y rompamos a través del combate juntos. 2. Configuración: Hola, amigos. Antes de que empecemos, deberías tener un proyecto con un personaje jugador que pueda moverse en un entorno, y algunos enemigos para que peleen. También es posible que desee tener un menú de inventario capaz de equipar artículos, incluyendo al menos un arma mala, un arma arreglada y un escudo A lo largo de este curso, agregaremos controles, mecánicas y animaciones a nuestro proyecto para bloquear un objetivo, atacar, esquivar, bloquear y disparar proyectiles 3. Lock On: Para nuestra primera lección, permitiremos que el jugador se bloquee en un enemigo. Comencemos agregando un mapeo de entrada para alternar el candado Abrir la configuración del proyecto, cambiar a la pestaña de mapa de entrada. Podemos agregar un evento de entrada llamado Toggle Lock. Desplazándose hacia abajo para encontrar el nuevo evento de entrada, uniré la tecla Q en el teclado y el botón derecho del stick en mi controlador a este evento En el guión de manejo de entrada del jugador, necesitaremos referencias al personaje, el brazo de resorte y la cámara, todo listo usando add on ready. Durante la función de entrada, después de verificar la pausa, abrir o cerrar el menú de inventario, y si el control del jugador ha sido desactivado. He dividido el resto de la entrada en cámara y controles de personajes para una mejor organización. Actualmente, el único control de la cámara es girar el brazo de resorte que sujeta la cámara usando el mouse. Comprobemos también si se presionó el botón de bloqueo de palanca. Esta será una entrada sensible al contexto con múltiples funciones posibles diferentes. Tendremos que saber si el jugador está actualmente bloqueado en un objetivo. Entonces, declaremos una variable para mantener el objetivo actualmente bloqueado como un nodo tres D, por lo que cualquier objeto tres D en nuestro mundo de juego podría potencialmente bloquearse en. Primero podemos dividir las funciones del botón de bloqueo de palanca en dos categorías posibles, si el valor de target es nulo o no, que podemos acortar a solo si target Empecemos en el bloque s donde el jugador no está actualmente bloqueado a nada. Aquí, tendremos que asignar el valor del objetivo para que sea el objetivo más visible, y podemos delegar la responsabilidad de averiguar cuál es el objetivo visible más cercano a la cámara En el caso de que no haya un objetivo visible más cercano, el objetivo seguirá siendo nulo. En muchos juegos de acción y aventuras, al presionar el botón de bloqueo de go, pero no hay nada en lo que bloquear. Luego, la cámara se restablece para estar detrás del personaje del jugador, que será una función del brazo de resorte Si el jugador ya está bloqueado en un objetivo y presiona el botón de bloqueo de Togo, también hay varios casos a considerar. Si hay múltiples objetivos visibles, el jugador se bloqueará en el siguiente objetivo visible más cercano, además del que está actualmente bloqueado. Podemos reutilizar la misma función de la cámara para encontrar el objetivo más cercano Pero esta vez también proporcionamos el objetivo actual como argumento, y vamos a escribir el algoritmo para ignorar este objetivo. En el caso de abajo, aún podemos pasar el objetivo actual ya que su valor es nulo, por lo que no tendremos nada que ignorar. Si no hay múltiples objetivos visibles, esta función también devolverá null y el bloqueo se desactivará Independientemente de si hay o no múltiples objetivos, si el jugador también está presionando hacia abajo, mayoría de los juegos desconectarán el bloqueo en ese caso. Podemos determinar si la dirección de entrada que se da es similar a abajo usando un producto de punto de los dos vectores, y comprobando si es mayor que 0.75. Esto cubrirá cualquier dirección cercana a abajo, pero no llegando hasta las diagonales Queremos tener la capacidad de alternar el bloqueo desde fuera del script, por lo que sería una buena idea convertirlo en una función pública. Vamos a llamarlo toggle lock y darle un parámetro opcional para forzar bloqueo con un valor predeterminado false. El valor de target se establecerá null si está siendo forzado a salir. De lo contrario, se puede ajustar al objetivo visible más cercano según lo determine la cámara, ignorando el objetivo actual si hay uno Los tres de estos casos anteriores ahora pueden llamar a Toggle lock con solo la necesidad especificar que el bloqueo se está forzando en el caso de que también se le dé la dirección de entrada hacia abajo, y otros scripts también pueden forzar al jugador a que se encienda o apague por cualquier motivo. Cambiar a la secuencia de comandos del brazo de resorte. Supongamos que el jugador presiona el botón de bloqueo de palanca, pero no hay objetivos visibles. Queremos que el brazo de resorte coloque la cámara detrás del personaje. Entonces necesitaremos una referencia al personaje al que está unido el brazo de resorte, que en mi caso siempre va a ser el nodo padre del brazo de resorte. Si está utilizando una estructura de nodos diferente, es posible que desee exportar esta variable en su lugar y establecer su valor en el panel del inspector. Para rotar la cámara detrás del personaje gradualmente con el tiempo, usaremos una variable de premezcla de tipo tween Sería una buena idea exportar una variable por la duración de la preadolescentes Voy a usar un cuarto de segundo. También podríamos querer un valor para la rotación x preferida para restablecer la rotación de los brazos del resorte dos. Usaré 0.5 radianes negativos, posicionando la cámara ligeramente por encima del personaje, mirando hacia adelante y ligeramente hacia abajo en ángulo También declaremos una variable para mantener la rotación del objetivo de los tweens como un vector tres e inicializarlo para que sea un vector tres con la rotación de reset x como su valor x, pero cero para las rotaciones y y z Dando una definición a la función, también podemos aceptar un parámetro opcional para la duración de la preadolescentes usando esto como su valor predeterminado para que pueda ser sobrescrito Para rotar la cámara detrás del personaje, podemos llamar a una nueva función privada para interponer la rotación de los brazos de resorte Especificando que queremos que la rotación y sea la rotación de plataformas de caracteres más una media rotación representada como radianes Pi A continuación, escribamos la función privada que preteje la rotación de los brazos de resorte, aceptando una rotación objetivo y como flotante, así como una duración para la premezcla con un valor predeterminado de la duración exportada Comenzaremos estableciendo la propiedad y de la rotación objetivo para que sea la rotación objetivo y aceptada como parámetro. Pero para asegurar que la rotación siempre tome el camino más corto alrededor del personaje, debemos envolver su valor para estar siempre entre el punto de rotación actual y menos una media rotación y el punto de rotación actual y más una media rotación. Si una preadolescente ya existe y se está ejecutando, entonces deberíamos matarla antes de crear una nueva Luego podemos interponer la rotación de los brazos del resorte a la rotación del objetivo a lo largo de la duración A continuación, dejemos que la cámara detecte objetivos visibles. Mi cámara aún no tiene ningún comportamiento con guión, así que agreguemos un nuevo guión y lo pongamos en la carpeta de scripts de reproductores Necesitaremos una función pública para obtener el objetivo visible más cercano, aceptando un parámetro opcional del objetivo actual con un valor predeterminado de null, por lo que potencialmente podemos ignorarlo. Esto devolverá un nodo tres D, y el caso predeterminado será devolver nulo si no pudimos encontrar un objetivo visible. Para determinar cuál de los objetivos visibles es el más cercano, necesitaremos mantener una lista de todos los objetivos visibles. Declaremos otra variable para contener todos los objetivos visibles como una matriz de nodos tres Ds. Inicializado para estar vacío. Una manera fácil de saber qué objetivos son visibles es adjuntar un nodo D de área tres a la cámara. Vamos a llamarlo rango objetivo. Esta zona estará monitoreando cualquier cosa en la capa de colisión 11, que he elegido para representar a los enemigos. Asegúrate de que tus enemigos tengan su capa de colisión establecida la misma capa que está siendo enmascarada por el bloqueo al apuntar También necesitaré restablecer las áreas transformadas para posicionarla en el origen de la cámara. El nodo D del área tres necesita una forma de colisión, y podemos poblar el recurso de forma con un polígono convexo Usando un polígono convexo, podemos definir la forma como una pirámide, que copia exactamente el campo de visión de la cámara, pero con un rango limitado Dado que el campo de visión de la cámara, tomará la forma de una pirámide de cuatro lados, podemos definirla con cinco puntos siendo el primer punto el mismo que la posición de las cámaras. Los otros cuatro se posicionarán a lo largo del eje Z, la distancia máxima de nuestro rango de bloqueo. Utilizaré una distancia máxima de 15 metros. Cambiando a la vista ortogonal superior y ocultando el entorno por un momento, simplemente ajustaré rápidamente las posiciones de cada punto de la pirámide para que coincidan aproximadamente con el campo de visión de las cámaras, 11.4 metros a la izquierda y a la derecha Asimismo, en vista ortogonal izquierda, ajustando los valores y de los puntos de la pirámide, 6.4 metros arriba y abajo. Hasta que tengamos forma de pirámide, coincidiendo con el campo de visión de las cámaras, que alcanza los 15 metros. Luego volveré a la vista en perspectiva y hablaré de la visibilidad del entorno nuevamente. Cada vez que un cuerpo ingresa a esta área, conectando la señal ingresada al cuerpo al guión de la cámara, podemos anexar el cuerpo a nuestra matriz de objetivos visibles Asimismo, cada vez que un cuerpo sale de esta área, el cuerpo puede ser borrado de la matriz Cualquier cuerpo de colisión de tres D en la capa 11, que exista dentro de esta área ahora se considerará un objetivo visible. En mi script de spring arm, necesitaré cualquier etiqueta para usar la función get parent. Ejecutando el juego y cambiando al árbol de escenas remoto, podemos seleccionar la cámara y ver sus propiedades en el inspector, incluyendo la matriz de objetivos visibles. A medida que la cámara se mueve por la escena, la matriz de objetivos visibles se actualiza automáticamente para agregar y eliminar a cada enemigo a medida que entran o salen del campo de visión. Al presionar el botón de bloqueo de palanca en realidad no apuntará a nada todavía, pero podemos ver cómo reposiciona la cámara detrás del personaje Antes de permitir el bloqueo a un objetivo, posible que también queramos verificar si la línea de visión del jugador hacia el objetivo está obstruida por el terreno También agreguemos un nodo de tres D de rayos emitidos a la cámara, y asígnele el nombre de línea de visión. Después agarra una referencia a ella en el guión de la cámara. Para encontrar el objetivo visible más cercano con nuestra cámara, si la matriz está vacía, su tamaño es cero, entonces no hay objetivos visibles a considerar, y deberíamos simplemente regresar. Si hay objetivos visibles a considerar, tendremos que comparar las distancias de cada uno con la cámara para encontrar cuál es la más cercana. Para ello, necesitaremos una variable para mantener la distancia desde el objetivo actual a la cámara como a flote La distancia más cercana como a flote, y el índice del objetivo visible más cercano como un entero Estableceremos la distancia más cercana a infinita usando la palabra clave I NF, y el índice más cercano a negativo para significar que no es un índice válido Si después de iterar a través de toda la matriz de objetivos visibles, el índice más cercano sigue siendo negativo, entonces ningún objetivo visible se consideró válido, y deberíamos devolver null De lo contrario, podemos devolver el objetivo visible en el índice más cercano. Si el objetivo visible en el índice I es el objetivo actual, podemos saltarlo con la declaración continuada. Para cualquier otro objetivo visible, necesitaremos calcular su distancia con respecto a la cámara. Podemos usar la distancia al cuadrado ya que es matemáticamente más eficiente Si la distancia actual es menor que la distancia más cercana, entonces tendremos que verificar si la línea de visión hacia este objetivo está obstruida Primero, tendremos que restablecer cualquier rotación que tenga actualmente la línea de visión. Luego establece la posición objetivo del rayo proyectado a la posición global del objetivo menos la posición global de la cámara y obligarla a actualizarla. Pero la posición de los personajes suele estar en el suelo, que es fácilmente obstruido por pequeños trozos de terreno y no siempre es un buen indicador de línea de visión Vamos a sumar también 1 metro arriba. Si la línea de visión choca con algo y ese algo es el objetivo visible, entonces la línea de visión no está obstruida por nada, lo que convierte a este objetivo en el objetivo visible más cercano que hemos encontrado hasta ahora Podemos establecer la distancia más cercana a la distancia actual y el índice más nerest a I antes de pasar por el resto de la matriz Esto ahora devolverá nulo o el objetivo visible más cercano a la cámara La línea de visión también estará colisionando con la capa 11, buscando enemigos, pero también capa uno para ser obstruida por También sería bueno hacerle saber al jugador en qué está encerrado con el indicador de objetivo. Agreguemos un nodo Sprite three D como hijo del controlador de entrada del reproductor y renombrémosle el indicador de destino Para la textura, usaré el puntero en blanco de la barra de desplazamiento. Pero cambia su configuración de entrada para activar Alpha pre multiplicado para que se vea un poco más suave. Y escalarlo a una cuarta parte de su tamaño. Después expandiendo la sección de bandera, pondré su bandera de cartelera para habilitarla, así que siempre va a mirar hacia la cámara. Y la bandera de prueba de no profundidad siempre dibujará el sprite sobre todo lo demás independientemente de su posición en el espacio tres D relativo a la cámara El indicador de objetivo puede ser invisible por defecto ya que el jugador inicia sin un objetivo para indicar. Agarrando una referencia al indicador de objetivo usando add on ready Entonces tendremos que colocarlo sobre el objetivo bloqueado. Entonces después de determinar en qué está encerrado el jugador , si hay un objetivo. Una manera fácil de hacer que el indicador de objetivo siga el objetivo es repararlo a ese objetivo. Luego podemos moverlo unos metros hacia arriba para colocarlo sobre la cabeza del objetivo y establecer su propiedad visible en true. Si no hay un objetivo que indicar, podemos reparar el indicador de nuevo a este nodo y volver a establecer su propiedad de visibilidad en caídas para ocultarlo. Vamos a probarlo. Cuando presionamos el botón de bloqueo de palanca, el enemigo más cercano es el objetivo, y el indicador se coloca sobre la cabeza del objetivo. Al presionar nuevamente el botón de bloqueo de palanca, interruptor está al siguiente enemigo más cercano. mantener presionado y presionar el botón de bloqueo de palanca, se fuerza el bloqueo. Si solo hay un objetivo visible que ya estamos bloqueados, bloqueo también se desactiva. Ahora tenemos al jugador encerrado a los enemigos en nuestro juego. En la siguiente lección, cambiaremos el comportamiento de la cámara y del personaje mientras están bloqueados. Te veré en la siguiente lección. 4. Strafe: Hola, amigos. En la lección anterior, agregamos un botón de bloqueo de palanca sensible al contexto a nuestro juego. En esta lección, cambiaremos la forma en que se comportan los nodos del jugador mientras se bloquean en un objetivo. Comenzando en el guión del jugador, una vez que se ha bloqueado un objetivo, emitamos una señal para que cualquier otro guión pueda escuchar y reaccionar al valor del cambio de objetivo, especificando lo que fue objetivo como parámetro. Usando un setter, podemos emitir la señal cada vez que se cambia el valor del objetivo por cualquier motivo Ahora los tres personajes, el brazo de resorte y la cámara pueden conectarse a la señal, usándola para establecer sus propias variables privadas para lo que se está apuntando. No importa cuál sea el valor de target en el script de manejo de entrada del jugador, todos los demás nodos también tendrán la misma información, incluso si se establece en null. Escribir una función simple para cada uno que establezca una variable objetivo local todos puedan acceder fácilmente a ella. Una vez que nuestro personaje se haya fijado a un objetivo, esperaríamos que se enfrentaran hacia el objetivo en lugar de mirar en la dirección en la que se mueven. En mi guión, la rotación del personaje se está haciendo en el proceso de física, que es decirle al personaje que mire hacia la dirección de la entrada de movimiento. Vamos a declarar una nueva variable en la parte superior del guión, quiere enfrentar la dirección como un tres. Y reemplace la dirección de entrada con quiere orientarse hacia la dirección en la llamada a la función. Entonces antes de esta llamada a la función, podemos verificar si el carácter está bloqueado en un objetivo. Si están encerrados a un objetivo, la dirección que van a querer enfrentar será hacia el objetivo, que podemos determinar fácilmente restando sus posiciones globales Si no están bloqueados, entonces querrán enfrentar la dirección de entrada de movimiento, igual que antes. Ahora el personaje se enfrenta al objetivo bloqueado, pero sus animaciones de movimiento locales no se ven muy bien, ya que solo se mezclan en función de la rapidez con la que se mueve el personaje y no en la dirección. En la máquina de estado del árbol de animación del personaje, están en el estado de salto inactivo porque no hay piso en la escena. El estado de movimiento loco es un espacio de mezcla unidimensional, mezcla las animaciones de marcha y carrera inactivas basadas en la velocidad de movimiento del personaje. Eliminemos este estado y lo reemplacemos por otra máquina de estado. Reconectando las transiciones a los otros estados, comenzando con una transición de inicio a locomoción para convertirlo en el estado predeterminado Tenía habilitada la transición al arranque en salto con un peso cruzado de 0.3 segundos. Y saltar tierra a locomoción cambiando al final con un destino cruzado de 0.67 segundos Omitiré la transición de locomoción a saltar inactivo temporalmente mientras trabajo en la máquina del estado de locomoción, por lo que el personaje permanecerá en el estado de locomoción y puedo ver los resultados Presionando el botón de reproducción forzará al personaje a entrar en el estado de locomoción y se pondrá porque actualmente está vacío Dentro del estado de locomoción, necesitaremos tener dos conjuntos diferentes de animaciones de locomoción para cuando el personaje está bloqueado en un objetivo y cuando no lo están y poder hacer una transición entre El valor por defecto será el mismo que antes, un espacio rubio unidimensional. Vamos a llamarlo no encerrado. Entonces también podemos agregar un espacio rubio bidimensional. Vamos a nombrar a este encerrado. Agregar una transición de inicio a no bloqueado hace que esta sea la predeterminada. Entonces podemos hacer la transición entre no bloqueado a bloqueado si el valor de target no es nulo, que podemos acortar a solo target y darle un corto desvanecido cruzado Y volver de nuevo a no bloqueado, si no objetivo con el mismo fundido cruzado. Dentro del espacio de mezcla no bloqueado . Podemos recrearlo exactamente como era antes, con un valor mínimo de cero mezclando animaciones inactivas, caminando y corriendo basadas en la velocidad de movimiento del personaje Con eso hecho, usa las migas de pan para subir un nivel a la máquina del estado de locomoción y presiona el botón de reproducción en la máquina de estado bloqueada para forzar al personaje a ese estado Dentro del espacio de mezcla bloqueado, combinaremos las animaciones en función qué dirección se mueve el personaje en relación con su dirección hacia adelante, que es hacia su objetivo. Voy a establecer el ajuste de la cuadrícula a incrementos de uno para facilitar las cosas Si posicionamos nuestra visión para estar detrás del personaje e imaginamos que están bloqueados en un objetivo frente a ellos, entonces el eje y representa la rapidez la que el personaje se mueve hacia o lejos del objetivo. El eje x representa la rapidez con la que el personaje se mueve hacia la izquierda o hacia la derecha, agachándose alrededor del objetivo Empecemos por poner la animación ociosa en el medio. Para el eje x, vamos a querer poner una animación de strafing left en el lado izquierdo y una animación el lado izquierdo y una strafing right en el lado derecho Para el eje y, podemos poner una animación de ejecución en la posición delantera, que generará triángulos en el espacio de mezcla mostrando cómo se mezclarán las diferentes animaciones se mezclarán Y agregando una animación caminando hacia atrás en la posición y negativa, también agregaremos más triángulos Si cambiamos la posición de mezcla, podemos ver cómo se verá el personaje mientras damos entrada de movimiento en cualquier dirección. Dependiendo de los activos que estés usando, también puedes tener animaciones de movimiento diagonal para agregar a este espacio de mezcla. En ocasiones esta vista previa no simula con precisión cómo se comportará el personaje mientras se ejecuta el juego. Y siempre debes probarlo jugando el juego para asegurarte de que se ve bien en el juego. Pero antes de hacer eso, volvamos al nivel raíz de la máquina estatal y agreguemos la transición de locomoción a saltar inactivo bajo la condición que el personaje no esté en el piso Solía cruzar el tiempo de fundido de 0.3 segundos para esta transición. También necesitamos actualizar la parte de nuestro guión, que establece la posición de mezcla del espacio de mezcla, que en el guión de mi personaje está sucediendo en la física del suelo. Seleccionando el árbol de animación, podemos copiar la ruta de propiedad de la posición de mezcla no bloqueada y actualizada en la función set. Pero esto solo necesita establecerse si el personaje no está bloqueado en un objetivo. Si están bloqueados en un objetivo, tendremos que establecer la posición de mezcla del espacio de mezcla bloqueado en su lugar. La posición de mezcla bloqueada es un vector dos con tanto una x como una y, que necesitaremos calcular. Así que vamos a declarar una variable para mantenerla llamada bloqueada en blend. Para evitar repetir los mismos cálculos varias veces, también declararé otra variable para almacenar la velocidad relativa del personaje, que será su velocidad x z dividida por su velocidad de carrera. Después de calcular este valor, la posición de mezcla del espacio de mezcla no bloqueado se puede establecer a la longitud de este vector. Si el personaje está bloqueado en un objetivo, podemos encontrar el valor x de la posición de mezcla usando el producto de punto del vector base global de plataformas x con su velocidad relativa El producto punto de dos vectores da como resultado un número que representa cuán similares o diferentes son. Entonces estamos comprobando cuán similar es la velocidad relativa del personaje a un vector que apunta directamente a su derecha. Dependiendo de cómo esté configurado tu personaje, qué dirección se considera hacia adelante, es posible que necesites multiplicar este valor por uno negativo para revertirlo. La posición de mezcla y también se puede determinar usando el mismo método, pero usando el vector z delantero del personaje. A continuación, mientras está bloqueada en un objetivo, la cámara debe mirar al objetivo, no al personaje del jugador. En la función de proceso de la cámara, ignorando a Delta, si hay un objetivo, podemos decirle a la cámara que mire al objetivo y sumando 1 metro hasta que no mire sus pies Al establecer el valor de objetivo, si el objetivo se establece en nulo, entonces podemos restablecer la rotación de la cámara para volver a la misma que su nodo padre, el brazo de resorte, ajustando su rotación al vector 30 También podríamos querer activar la función de bloqueo si el objetivo actual sale de nuestro límite de rango visible. éter se bloquea o cambia automáticamente a un objetivo más cercano. Entonces, agreguemos una señal para cuando el objetivo actual salga del rango y emitamos si el cuerpo que salió del área es el objetivo actual Entonces podemos conectar esta señal al guión de manejo de entrada del jugador. Llamando a la función de bloqueo de palanca. Dependiendo de si desea que el comportamiento cambie al objetivo más cercano o simplemente se bloquee, es posible que desee vincular un argumento verdadero para la fuerza del parámetro. En el guión del brazo de resorte, mientras está bloqueado en un objetivo, vamos a querer que el brazo de resorte apunte siempre lejos del objetivo para mantener tanto el objetivo como el personaje del jugador a la vista de la cámara. Vamos a agregar una nueva variable para mantener esa dirección como un vector tres. Entonces, cuando se está estableciendo el valor del objetivo , si no es nulo, entonces podemos establecer el valor de la dirección del objetivo para que sea la diferencia en nuestra posición global menos la posición global del objetivo. Esto dará como resultado un vector apuntando desde el objetivo de nuevo al personaje del jugador. Entonces podemos volver a usar la función de rotación de tween, pero se espera un parámetro float que represente una rotación y Podemos obtener la rotación y, que apuntará en esta dirección usando la función de trigonometría, A t dos, dándole los valores x y z de nuestra Una vez que se ha establecido el objetivo, el brazo de resorte girará la cámara alrededor para estar en la dirección opuesta al objetivo detrás del jugador. Pero queremos que se quede ahí. En la función de proceso, si se ha establecido el valor de target y entre paréntesis, si o bien la tween no existe o no se está ejecutando, es decir, la tween ha terminado y el brazo de resorte está en posición, entonces podemos realizar los mismos cálculos, pero simplemente establecer el valor de rotación y directamente en lugar de hacer Esto mantendrá el brazo de resorte apuntando lejos del objetivo, mientras está bloqueado en el objetivo, manteniendo el objetivo y el personaje del jugador a la vista de la cámara. Por último, en el guión de manejo de entrada del jugador, queremos evitar que el jugador gire el brazo de resorte mientras está bloqueado en un objetivo. Esto está sucediendo en dos lugares diferentes en mi script, uno para controles de PC usando el mouse, y otro para soporte de controlador con el stick derecho. Así que simplemente envolveré ambos en una declaración if para no permitir estas entradas mientras están bloqueados en un objetivo. Vamos a probarlo. Cuando nos fijamos en un enemigo, la cámara enfoca el objetivo, mientras que el brazo de resorte gira para posicionar la cámara en la dirección opuesta. Al mover al personaje, rotan para enfrentar al enemigo y animar movimientos fluidos en todas las direcciones El brazo de resorte mantiene la posición de la cámara de estar detrás del personaje, apuntando lejos del objetivo, mientras la cámara continúa mirando al objetivo. Los controles normales de la cámara del jugador se han desactivado mientras están bloqueados. Si el objetivo bloqueado está fuera de rango, entonces cambiará automáticamente al objetivo más cercano o se bloqueará si no hay uno en el que bloquearse. Si forzamos a bloquear, entonces la cámara vuelve a enfocar el personaje del jugador, se reanuda el control normal del brazo de resorte y las animaciones de locomoción de los personajes vuelven a Ahora tenemos nuestros nodos de jugadores adaptando sus comportamientos para estar bloqueados en un objetivo. En la siguiente lección, haremos que el personaje jugador realice ataques. Te veré en la siguiente lección. 5. Ataque: Hola, amigos. En la lección anterior, cambiamos el comportamiento de los nodos del jugador mientras estaban bloqueados en un objetivo. En esta lección, agregaremos animaciones de ataque para que los personajes puedan atacarse entre sí. Comencemos abriendo la configuración del proyecto, la pestaña del mapa de entrada y agregando un nuevo evento de entrada para atacar. Usaré el botón izquierdo del ratón y el botón del hombro derecho en mi mando. Luego en el script del controlador de entrada del jugador, podemos verificar si se presionó el botón de ataque al verificar las entradas de control de caracteres Si se presionó el botón de ataque este fotograma, entonces deberíamos decirle al personaje que ataque. Pero, ¿y si el personaje está ocupado? Podrían estar saltando o realizando alguna otra acción y quizá no queramos que puedan atacar en este momento. Requerir que el jugador espere hasta que sea posible atacar antes de presionar el botón sería bastante frustrante La mayoría de los juegos modernos considerarán que la pulsación es válida por un corto tiempo después de presionar el botón, lo que se conoce como búfer de entrada Agreguemos un tiempo o nodo al controlador de entrada del jugador. Denle el nombre buffer de entrada y establezca su propiedad one shot en true, por lo que solo contará atrás una vez a la vez. Agarrando una referencia a este temporizador de búfer de entrada usando add on ready, podemos iniciar el temporizador después de decirle al personaje que ataque, luego esperar su señal de tiempo de espera. Después de que el temporizador haya contado atrás a cero, entonces le diremos al personaje cancele la instrucción que se le dio para atacar. Por lo que en cualquier momento mientras el temporizador está contando atrás, el personaje intentará atacar cuando esté listo. El tiempo de espera predeterminado para el temporizador es de 1 segundo, que es una cantidad razonable de tiempo para el búfer de entrada de ataque. Otra entrada que podríamos querer almacenar en búfer es la entrada de salto. Siguiendo el mismo patrón que la entrada de ataque, podemos iniciar el temporizador, esperar su señal de tiempo de espera, luego cancelar la entrada de salto. En el guión del personaje, comencemos por crear una nueva región de código para el combate. Luego mueve la función objetivo del jugador a esta región. Necesitaremos una función pública para decirle al personaje que ataque y otra para decirle que cancele la instrucción. La función de salto también necesitará una función de coincidencia y cancelación de salto dos. El propósito principal de estas funciones es establecer variables que serán verificadas por el árbol de animación que sepa a qué estados viajar. En la parte superior del guión, agregaremos más variables para indicar intenciones del personaje de lo que quiere hacer a continuación, entradas Buffered como Booleanos, ya sea que quieran saltar o quieran atacar Entonces la función de ataque establecerá la variable wants to attack en true y cancel attack volverá a establecerla en false. Dado que la entrada está siendo almacenada en búfer, ya no necesitamos exigir que el personaje pueda moverse o estar en el piso, y podemos delegar esa responsabilidad a la máquina de estado de árboles de animación. Y tampoco necesitamos decirle a reproducción de la máquina de estado del árbol de animación que viaje al estado de inicio de salto. Haremos esta transición automática si se cumplen las condiciones. Pero no queremos que ambas variables sean ciertas al mismo tiempo. El personaje querrá saltar o atacar, no ambos. Entonces, cada vez que una entrada en búfer se establece en true, todas las demás se establecerán false, anulando la instrucción En la escena del personaje, seleccionando el árbol de animación y cambiando al panel del árbol de animación, podemos ver la máquina de estado. Cambiemos la transición que lleva de locomoción a inicio de salto para que sea automático bajo la condición de que el personaje esté en el piso y pueda moverse y quiera saltar Ahora el personaje saltará automáticamente tan pronto como puedan dentro de 1 segundo después de presionar el botón de salto. Esto es particularmente útil para encadenar saltos uno tras otro, ya que el jugador podrá presionar el botón de salto antes de golpear el suelo Pero mirando la máquina de estado de salto, consideremos cómo incorporar las animaciones de ataque. Podríamos pasar de la locomoción al ataque y volver de nuevo. Pero las animaciones quedarían mal si queremos que el personaje pueda moverse mientras ataca. No permitiría que el personaje atacara mientras saltaba. En cambio, sería mejor separar las animaciones que implican mover al personaje de las de realizar acciones. Si su máquina de estado aún no se ha guardado como recurso de proyecto, haga clic en el menú desplegable junto a Raíz de árbol y seleccione Guardar como. Ya guardé el mío en la carpeta de escenas de personajes y lo llamé animaciones de personajes. Pero voy a cambiarle el nombre a movimientos de personajes. Con la máquina de estado guardada, eliminémosla del árbol de animación del personaje y, en su lugar, la reemplacemos con un árbol de mezcla de nodos de animación. El panel del árbol de animación ahora muestra un gráfico, que contendrá nuestro árbol de mezcla, lo que nos permite combinar cualquier cantidad de animaciones juntas. Pulsando con el botón derecho en el espacio vacío, selecciona cargar. Después navega por los recursos de tu proyecto para encontrar tu máquina de estado de movimiento de personajes. La máquina de estado que estábamos usando anteriormente ahora es un nodo en el gráfico de árbol Blend, y el resultado de la máquina de estado se emitirá por el pin en su lado derecho. Si conectamos la salida de la máquina de estado a la salida del árbol de mezcla, entonces la animación funcionará tal como lo hacía antes. Pero el propósito del árbol de mezcla es mezclar múltiples animaciones juntas. Desconectemos el pin. Después haga clic derecho y agregue un nodo blend two. El nodo blend two comenzará con la animación conectada a su pin de entrada y se fusionará en un porcentaje de la animación conectada a su pin de entrada de fusión. El resultado de esta mezcla se emitirá desde el pin en el lado derecho, que podemos conectar a la salida de los árboles de mezcla. La animación que queremos mezclar con los movimientos del personaje serán las acciones del personaje, es decir, sus ataques. Podemos agregar otra máquina de estado al árbol de mezcla y darle el nombre de acción. Luego conecte su salida al pin de entrada de mezcla de dos nodos de mezcla de mezcla. A continuación, abriremos la máquina de estado de acción e iniciaremos el personaje en la animación inactiva. Transición de inicio a inactivo para convertirlo en el estado de acción predeterminado A continuación, necesitaremos una vista de nuestro personaje y para iniciar tanto las máquinas de estado de movimiento como de acción haciendo clic en el botón de reproducción en sus respectivos estados de inicio. Luego regresa a la raíz del árbol de mezcla. Nuestro personaje todavía parece estar en la animación de salto inactivo porque el porcentaje de la animación de acción que se mezcla en ella es actualmente cero. Si arrastramos el mango sobre uno, podemos ver que la animación cambia gradualmente de salto inactivo a inactivo. A continuación, haga clic en el botón de editar filtros y active habilitar filtrado. Alejemos la ventana para que podamos ver a nuestro personaje a medida que filtramos huesos individuales, decidiendo a qué huesos se deben aplicar nuestras animaciones de acción y cuáles no. Enciende todos los huesos que componen la parte superior del cuerpo del personaje. Ahora la parte inferior del cuerpo del personaje, incluida su posición, está siendo afectada por el estado de movimiento. Salta inactivo, mientras su parte superior del cuerpo está siendo controlada por su estado de acción inactivo. Esto nos permite combinar estas animaciones de tres maneras diferentes. Si el personaje se mueve pero no realiza ninguna acción, entonces la cantidad de mezcla será cero, usando solo la salida de la máquina de estado de movimiento. Si el personaje está realizando una acción pero no se mueve, entonces la cantidad de mezcla será uno, y los filtros se apagarán, usando solo la salida de la máquina de estado de acción. Si el personaje se está moviendo y realizando una acción, entonces los filtros se encenderán. Usando la salida de la máquina de estado de movimiento para la parte inferior del cuerpo del personaje y la salida de la máquina de estado de acción para su parte superior del cuerpo. Vamos a nombrar a esta mezcla dos nodos inferior más superior, ya que está fusionando las animaciones de la parte superior del cuerpo en las animaciones de la parte inferior del cuerpo. Pero si la cantidad de mezcla es cero o uno, entonces las animaciones en una de las máquinas de estado no se ejecutarán para ahorrar en tiempo de procesamiento, lo que puede resultar en algunos problemas si estamos confiando en ellas para establecer propiedades o llamar métodos. Puede ser útil tener siempre ambas máquinas de estado funcionando en todo momento, aunque el personaje no esté realizando ninguna acción o no se mueva. Para asegurar que ambas máquinas de estado estén siempre activas, podemos establecer la cantidad de mezcla en 1%, y al realizar una acción, aumentarla a 99%. Podemos suponer que debe comenzar con una cantidad de mezcla de 1% ya que el personaje no estará realizando ninguna acción cuando se cargue por primera vez. De vuelta en el guión del personaje, dado que el árbol de animación va a volverse mucho más complejo, sería una buena idea abstraer sus comportamientos en su propio guión. Podemos eliminar la variable de reproducción de la máquina de estado del script de caracteres y agregar un nuevo script al árbol de animación. Lo guardaré en la carpeta de scripts de caracteres. En los árboles de animación nuevo guión, nuestro principal objetivo es crear las tres mezclas de animación que acabamos de mencionar. En la función process, necesitaremos establecer el parámetro de cantidad de mezcla como hicimos con los espacios de mezcla. Copiar la ruta de propiedad y especificar una cantidad de mezcla. Hagamos que la cantidad de mezcla sea una variable flotante privada con un valor predeterminado de 1%, y pasemos esto como argumento. Entonces tendremos que cambiar el valor de la cantidad de mezcla en función de si el personaje está realizando o no una acción. Almacenemos la reproducción de las máquinas de estado de acción en una variable. Esta vez, usando la palabra clave self, ya que este script se adjunta al árbol y usando la ruta de propiedad para la reproducción de la máquina de estado de acción. Entonces en la función de proceso, podemos verificar en qué nodo se encuentra actualmente la reproducción del estado de acción. Y si está en el estado inactivo, entonces eso significa que el personaje no está realizando ninguna acción, y podemos establecer la cantidad de mezcla en 1%. De lo contrario, están realizando una acción y podemos fijarla al 99%. Pero esto será un cambio instantáneo que podría parecer un poco nervioso Entonces, en lugar de establecer la variable directamente en 1% o 99%, vamos a moverla hacia ese número en una pequeña cantidad a lo largo del tiempo. Usando la función mover hacia, podemos partir de lo que es actualmente la variable, moviéndola hacia lo que queremos que sea por Delta. Esto hará que la transición tome 1 segundo, lo que es un poco largo. Así que vamos a multiplicar Delta por una nueva variable para mantener la velocidad de mezcla, que voy a dar un valor predeterminado de cuatro. La transición tomará un cuarto de segundo. Para activar o desactivar los filtros, necesitaremos acceder directamente al nodo blend two. Entonces declarando una variable para mantenerla, que es de tipo animación nodo mezcla dos Podemos acceder a él a partir de la raíz del árbol de árboles de animación, usando la función get node. Esta función acepta un nombre de cadena, que podemos especificar como el mismo nombre que le dimos al nodo en el gráfico de árbol de mezcla, inferior más superior. Ten cuidado de que la ortografía sea exactamente igual. No se nos permite activar o desactivar los filtros mientras se procesa el árbol de animación. Entonces hagamos una función pública para dejar que el guión del personaje haga esto por nosotros, diciéndole al árbol de animación si el personaje se está moviendo o no. Si el personaje se mueve, entonces los filtros deben estar habilitados para mezclar las acciones de la parte superior del cuerpo con los movimientos de la parte inferior del cuerpo. Si el personaje está estacionario, entonces los filtros se pueden desactivar para usar solo las animaciones de acción. Mientras estamos aquí, agreguemos también dos funciones más para establecer las cantidades de mezcla de los espacios de mezcla de locomoción para mantenerlos abstraídos del guión del personaje Establecer bloqueado en mezcla, aceptando un parámetro de vector dos para la cantidad de mezcla, estableciendo el parámetro de cantidad de mezcla del espacio de fusión bloqueado en. Y establecer no bloqueado en la mezcla, aceptando un parámetro de flotación para la cantidad de mezcla, estableciendo el parámetro de cantidad de mezcla del espacio de fusión no bloqueado en. De vuelta en el script de caracteres, podemos ver que las rutas de propiedad a las cantidades de mezcla ya no son válidas, ya que no hacen referencia a la máquina de estado de movimiento. Resumiendo estas funciones, mantendremos cualquier cambio en el árbol de animación contenido dentro de su propio guión En el proceso normal de física, también tendremos que decirle al árbol de animación si el personaje se está moviendo o no actualmente. Sin embargo, ahora estamos asumiendo que cada personaje debe tener este guión adjunto a su árbol de animación, y que están usando el mismo árbol de animación. Así que vamos a guardar nuestro nuevo árbol de animación como recurso de proyecto. Lo pondré en la carpeta de escenas de personajes, junto con la máquina de estado de movimiento de personajes. Después actualice cada uno de los otros personajes para usar el nuevo árbol de animación y adjuntarle el guión, que todos funcionen de la misma manera. Solo estoy usando el Bárbaro y los esqueletos en este proyecto, pero el mago nocturno y el pícaro también deberían actualizarse si los estás Sin embargo, esto crea un nuevo problema. Si cada carácter comparte el mismo recurso de árbol de mezcla, entonces cambiar la propiedad enable filters para un carácter la cambiará para todos los caracteres. Podemos sortear esto dando a cada personaje su propia copia única del árbol de mezcla. Para evitar tener que replicar cada cambio en el árbol de mezcla de cada personaje cada vez, usaré un simple atajo En el script del árbol de animación, durante la función ready, estableceré la propiedad raíz del árbol para que sea un duplicado del árbol de mezcla. Pasar true como argumento también duplicará cualquier subrecurso que este recurso esté utilizando. Desde el árbol de mezcla, este árbol de animación está usando ya que su raíz ya no es la misma que se le asignó originalmente. Tendremos que asignar los valores de la reproducción del estado de acción y el nodo blend two después de esta duplicación. Ahora cada vez que se carga un personaje, harán su propia copia única del árbol de mezcla y podrán cambiar su comportamiento de filtrado sin afectar a otros personajes. Volvamos a la máquina de estado de acción de personajes. Nuestro personaje aún no tiene ningún objeto equipado, así que vamos a hacer la transición a ídolos desarmados Por ahora, hagamos que la condición para esta transición sea si están apuntando a un enemigo o si quieren atacar usando un corto desvanecedor cruzado, y pueden hacer la transición de regreso si no están apuntando a un enemigo y no quieren atacar. Entonces para mantener las cosas organizadas. También agregue otra máquina de estado llamada ataques desarmados, y haga la transición a la máquina de estado si el personaje quiere atacar Luego pueden hacer la transición de nuevo a ídolo desarmado al final de la animación de ataque Edición de la máquina de estado desarmada. Empecemos con un golpe de ataque masculino desarmado A. Esto hará la transición al final o al golpe de ataque masculino desarmado B al final de la animación en función si el personaje quiere o no volver a atacar Podemos repetir este patrón haciendo la transición a una patada de ataque masculina final o desarmada al final de la animación, en función de si el personaje quiere o no atacar una vez más. Y podemos crear un combo de ciclismo sin fin haciendo la transición de nuevo al primer golpe siempre y cuando el jugador siga presionando el botón de ataque Cuando dejan de presionar el botón de ataque, la máquina de estado pasará a terminar, lo que volverá a estar inactivo desarmado También podríamos querer restringir cómo se mueve el jugador mientras ataca. Por ejemplo, no tendría ningún sentido que el personaje se moviera en absoluto durante la animación de patada, ya que sus pies deberían estar ocupados. Acercaré la pantalla de la pista de animación para ajustarme mejor a la longitud de estas animaciones. Agreguemos una función pública al script de caracteres para restringir el movimiento, aceptando un parámetro booleano para saber si el personaje puede moverse o no Luego estableceremos el valor de la variable move para que sea lo contrario. En la animación de patada del personaje. Podemos agregar una pista de método de llamada llamando a un método en el nodo raíz del personaje. Llamar a la función de restricción de movimiento al inicio de la animación, pasando true como argumento, restringiendo el movimiento del personaje mientras patea Y otra clave al final de la animación puede restaurar la capacidad del personaje para moverse cambiando el argumento a falso. Pero para que esto funcione, necesitamos regresar al árbol de mezcla y agregar funciones a los filtros blend two nodes para que si el personaje se está moviendo y realizando una acción, se llamará a las funciones actions. L et's pruébalo. Nuestras animaciones parecen estar funcionando como lo hacían antes. En cuanto le decimos al personaje que ataque, hacen la transición al estado inactivo desarmado antes de realizar un ataque Si seguimos ciclando, seguirán atacando repetidamente, recorriendo en bicicleta las diferentes animaciones de ataque desarmado Incluso es posible moverse o saltar mientras ataca, y el personaje utilizará las animaciones adecuadas para su parte superior e inferior del cuerpo, pero no se le permite moverse o saltar mientras patea Si nos bloqueamos en un objetivo, el personaje pasa al estado inactivo desarmado y bloqueando las transiciones de regreso al ídolo normal Ahora tenemos a nuestro personaje realizando ataques desarmados. En la siguiente lección, agregaremos animaciones de ataque con armas. Te veré en la siguiente lección. 6. Arma: Hola, amigos. En la lección anterior, mezclamos las acciones de la parte superior del cuerpo con los movimientos de la parte inferior del cuerpo, permitiendo que nuestro personaje realice ataques desarmados En esta lección, también agregaremos una variedad de animaciones de ataque con armas. Empecemos en el árbol de animación de personajes donde ya tenemos ataques inactivos y desarmados desarmados Siguiendo este patrón, agregaremos la animación inactiva a dos manos. En este paquete de activos, no hay animaciones inactivas de una sola mano o de dos ruedas Pero solo podemos agregar dos nuevas copias de la animación inactiva y cambiarles el nombre. A partir de cada una de estas animaciones inactivas, entonces podemos conectarnos a máquinas de estado de ataque que funcionan igual que los ataques desarmados Conectando desde cada una de las animaciones inactivas a los ataques si el personaje quiere atacar, y regresando al final de la animación. Solo necesitamos una forma de decirle al personaje qué conjunto de animaciones usar en función de su arma equipada. En este proyecto, tenemos un guión llamado enums, contiene todas nuestras enumeraciones, a las que agregaremos otro tipo de arma Comenzando con desarmado como predeterminado, luego enumerando cada uno de los diferentes tipos de armas que necesitan diferentes animaciones, mala con una mano, mala a dos manos y doble rueda Es importante saber que la enumeración es solo una lista numerada, por lo que cada uno de estos valores son en realidad números, comenzando por ser cero desarmado, una mano es una, dos manos es dos, y doble rueda es tres En el script de caracteres, agregaremos otra variable llamada attack animation con un tipo de nuestra nueva enumeración Podemos exportar esta variable con fines de prueba. L et's cambian la animación de ataque del personaje a otra cosa que no sea desarmada Usaré cuerpo a cuerpo a dos manos. De vuelta en la máquina de estado de acción, podemos establecer la condición de transición para pasar de inactivo a inactivo desarmado para ser si la animación de ataque del personaje es cero, que está desarmada en nuestra enumeración, y también al menos una de las otras condiciones poniéndolas La condición de retorno será entonces también lo contrario. O la animación de ataque no es cero, o se cumplen las otras dos condiciones. Al agregar transiciones a cada uno de los diferentes estados de inactividad, podemos establecer sus condiciones para que sean las mismas que inactivas desarmadas, solo usando un valor diferente para la animación de ataque Voy a dar a cada uno de ellos el mismo tiempo de fundido cruzado también. Después haciendo la transición de nuevo al ralentí bajo las condiciones lógicamente opuestas Dentro de cada una de las máquinas de estado de ataque, podemos usar las animaciones de ataque de la misma manera que hicimos con los ataques desarmados Hay cuatro diferentes ataques con una sola mano, creando un ciclo de diferentes animaciones siempre y cuando el personaje quiera seguir atacando. Repitiendo el mismo proceso para los ataques a dos manos, que sólo tiene tres ataques diferentes. Y la máquina estatal de doble rueda también sólo tiene tres ataques Podemos probar esto en el juego, ya que la animación de ataque de los personajes está establecida en dos manos, utilizan las animaciones de ataque a dos manos. Podemos decirles que usen animaciones de ataque con una mano o animaciones de doble rueda también Ahora, solo necesitamos cambiar la variable al equipar elementos al personaje En los recursos personalizados, necesitaremos una clase más específica para describir un arma que hereda del equipo Dándole el nombre de clase arma, podemos agregar una variable exportada extra para almacenar el tipo de arma que es, y podemos usar la misma enumeración que el Entonces cualquiera de los recursos de ítem en el proyecto que son armas pueden ser reclasificados como armas, dándoles un valor por su tipo de arma, por lo que el personaje sabrá qué animaciones usar al equiparlos Para fines de demostración, actualizaré la x para que sea un arma con una sola mano. Recuerde repoblar los campos que no se traspasen al cambiar el script de recursos El grado como arma a dos manos, y la daga como arma de doble rueda. En el guión int o en el que sea que estés usando para equipar objetos, necesitaremos una excepción para si el objeto que se está equipando es un arma Y si es un arma a dos manos o un arma de doble mano, entonces tendremos que quitar cualquier cosa que el personaje tenga equipado en su ranura fuera de la mano C agitando primero si el archivo, el conjunto de equipos de progreso tiene algo equipado en la ranura de mano Luego lo usaré para indexar los botones del ítem en el inventario del jugador y quitaré la E para equipar del botón. Luego, también establezca el valor de las matrices de equipos en negativo uno o vacío. Entonces le diré al personaje que dof cualquier equipo en su toma de mano En el guión del personaje, el personaje necesitará saber qué tiene en sus manos. Agreguemos variables de tipo nodo tres D para sostener su mano principal y su equipo fuera de mano. Nuestro personaje que se ponga un arma también puede tener algo de lógica adicional agregada para si el objeto es un arma El objeto de la mano principal del personaje se puede asignar entonces a esta arma, y las animaciones de ataque de los personajes se pueden configurar para que coincidan con las del arma que se está equipando. Si el objeto es un arma tipo rueda doble, también agregaré otra copia duplicada del arma en la toma de mano del personaje. Y asignarlo a la variable off hand. Al quitarse una pieza de equipo, si ese equipo se está quitando de la mano principal del personaje, entonces podemos establecer la variable de mano principal null y también verificar si actualmente son de doble Si es doble empuñando, le diré al personaje que haga el artículo también en su mano apagada Y luego configuraré la animación de ataque a desarmada. Asimismo, si el socket que se está quitando es el off hand, entonces deberíamos establecer la variable offhand Ya no necesitamos exportar la animación de ataque, ya que ahora la establecerá el arma equipada. Ahora el personaje comienza a usar ataques desarmados. Pero cuando está equipado con un arma de una mano cambia a usar ataques con una sola mano. Podemos equiparlos con un escudo, luego cambiar a un arma a dos manos, y el escudo se eliminará automáticamente. El personaje ahora usa animaciones de ataque a dos manos. Cambiando a las dagas de doble rueda, el personaje tiene una daga en ambas manos y usa las animaciones de ataque de doble rueda Un equipando las dagas, el personaje vuelve a usar ataques desarmados Lo último que necesitan nuestros ataques son cajas de cadera. Áreas de colisión para detectar si el ataque realmente golpea a un enemigo e inflige daño. Al abrir las escenas de armas, podemos agregar cajas de golpes a cada una de ellas. Usar un nodo D de área tres, que no será monitoreado o monitoreable por defecto, ni tendrá ninguna capa de colisión o máscara de colisión hasta que se les indique que lo hagan Dado que estos modelos de personajes tienen extremidades cortas y armas pequeñas, sus ataques no llegan muy lejos. Entonces voy a ser muy generoso con sus cajas de cadera, haciéndolas más grandes que las armas reales. Crear un nuevo guión para las armas, heredando del ítem Reemplazaré el script adjunto al nodo raíz de armas y lo abriré para editarlo. Podemos decirle al arma que agarre o haga referencia a su caja de impacto usando add on ready. Luego agrega funciones para establecer la máscara de colisión de cajas de impacto en un nuevo número entero. Y otro que activará o desactivará el hit box configurando su propiedad de monitoreo El personaje que sostiene esta arma ahora puede especificar en qué capa de colisión están sus enemigos y activar la caja de impacto al balancear el arma. El modelo de personaje también necesitará una caja de cadera para ataques desarmados Al igual que las armas, no necesita ser monitoreada, monitoreable, ni tener una capa de colisión o máscara de colisión y tendrá una forma de colisión sobredimensionada Pero no necesitamos posicionarlo ahora mismo y podemos delegar esa responsabilidad en las animaciones. En el guión del personaje, podemos tomar una referencia a la caja de cadera desarmada usando add on ready Recuerda agregar una caja de cadera a cada personaje o usar la función get node o null para evitar errores. También exportemos una capa de física de tres D para contener la capa de colisión de los enemigos de este personaje. Esto agregará una cuadrícula de números en el inspector al igual que las capas de colisión en el área tres propiedades de notas D. De esta manera, podemos especificar que este personaje estará tratando de golpear cosas en la capa de colisión enemiga Hurt, que he dicho que es la capa 18. Mientras tanto, los enemigos que usan el mismo guión pueden establecer su capa de colisión enemiga para que sea la capa de colisión HRT del jugador Durante la función ready, podemos configurar la máscara de colisión de la caja de cadera desarmada para que sea la capa de colisión del enemigo De igual manera, cada vez que se equipa un arma, podemos establecer su máscara de colisión para que sea la capa de colisión del enemigo, así sabrá qué capas enmascarar independientemente de quién la sostenga. Entonces necesitaremos algunas funciones en el guión del personaje para activar y desactivar las cajas de cadera de las armas durante las animaciones de ataque, aceptando un parámetro booleano para especificar si la caja de cadera se está activando o desactivando y un entero Y le voy a dar un valor por defecto de uno para significar la mano principal. Usando una declaración de coincidencia, podemos crear tres casos separados, activando la caja de cadera para ataques desarmados, ataques mano principal o ataques fuera de la mano Si está desarmado, podemos activar la propiedad de monitoreo de la caja de cadera desarmada Si es mano principal o de mano, entonces podemos decirle al arma active o desactive su caja de impacto Nuestras animaciones de personajes pueden entonces tener pistas agregadas a ellos para activar y desactivar los hit boxes Yo sólo voy a demostrar con un ataque de cada tipo, comenzando con un ataque masculino de una mano chuleta. Al agregar una pista de método de llamada a esta animación, generalmente esperaríamos que el hit box se active justo después de que comience a balancearse. Añadiendo una clave en este momento, podemos cambiar el argumento booleano a true para activar el hit box del arma principal del personaje. Después se desactivó al final del swing cambiando el argumento a false Esto evitará que los enemigos entren en el arma cuando no se mueve se vean perjudicados por ella, y solo inflige daño cuando el personaje realmente está balanceando el arma con fuerza El proceso es el mismo a la hora empuñar un arma en las manos. Al agregar una pista, luego se llama a la función de encuadre de teclas para activar el cuadro de aciertos al inicio del swing del arma y desactivarlo al final del Al empuñar doble, necesitaremos especificar qué caja de cadera se está activando, ya sea la mano principal o la mano apagada, cambiando también el parámetro entero a dos, si la caja de cadera que se activa o desactiva pertenece al arma off hand Y al desarmarnos, no solo necesitaremos activar la caja de cadera, sino también posicionarla para que esté en la ubicación correcta Usando una pista de propiedad para enmarcar la propiedad de posición de cajas de cadera. Luego cambiaremos el argumento entero en las llamadas a la función a cero para indicar que queremos usar el hip box desarmado Es una buena idea asegurarse de que la caja de cadera esté en posición al menos un cuadro antes de activarlo. Ayuda a usar vistas ortogonales para posicionar la caja de cadera exactamente en el puño del personaje desde al menos dos ángulos diferentes. A continuación, haga clic en el icono de clave para enmarcar esta posición en la animación. No podremos probar estas cajas de cadera hasta la siguiente lección cuando agreguemos cajas lastimadas para que las golpeen. El hip box no sólo se activará con la animación, sino que luego también seguirá el puño del personaje. Recuerda que necesitarás completar este proceso para cada animación de ataque. Ahora tenemos a nuestro personaje atacando con diferentes animaciones para cada tipo de arma. En la siguiente lección, permitiremos que los personajes se lastimen y sufran daños. Te veré en la siguiente lección. 7. Golpe: Hola, amigos. En la lección anterior, agregamos cajas de golpes a nuestras armas y animaciones de ataque. En esta lección agregaremos cajas de Hurt a nuestros personajes para que puedan ser golpeados por ataques. A personajes Hurt box es sólo otra zona tres nodo D. Vamos a añadir a los modelos de personajes. No estarán monitoreando, sino que serán monitoreables por las casillas de impacto Existirán ya sea en la capa de caja Hurt de jugadores o en la capa de caja de corazón del enemigo apropiadamente. Pero no es necesario enmascarar nada ya que no están monitoreando de todos modos. Para la forma de colisión de cajas Hert, otra cápsula es muy común, pero suele ser más pequeña que la forma de colisión del cuerpo del personaje y completamente contenida dentro del modelo de personaje No le parecería justo al jugador ser golpeado por algo que no parece hacer contacto. Ten en cuenta que las armas están usando cajas de cadera de gran tamaño, por lo que las cajas hert también serían razonables, pero haré que las mías se ajusten a la cabeza y al cuerpo del personaje Luego copiaré y pegaré la misma caja hert en las escenas de mis personajes enemigos, cambiando su capa de colisión a la capa de HRT enemiga Entonces en nuestras escenas de armas, usaré el hacha como ejemplo. Tendremos que conectar la señal ingresada en el área del hit box al guión del arma. Si esta caja de golpe de armas entra en la caja de daño de un personaje, entonces necesitaremos esta arma para infligir daño a ese personaje Por ahora, agreguemos una variable pública para este daño armamentístico. Cuando ocurra la colisión, necesitaremos una referencia al personaje al que pertenece la caja Hurt. En mi proyecto, ese siempre será el nodo padre de la caja Hurt. Entonces podemos decirle al personaje que tome daños, pasando como argumento el daño de las armas. También podría ser agradable saber la dirección de la que proviene el daño. Entonces podemos usar la diferencia entre sus posiciones globales normalizadas. Para mantener toda la información de nuestras armas en un solo lugar, su daño debe agregarse al archivo de recursos como una variable exportada, y le daré un valor predeterminado de dos daños. Cada archivo de recursos de arma diferente puede especificar entonces cuánto daño infligirá esa arma Recuerda conectar también la señal ingresada por el área para cada escena de arma. De igual manera, la caja de cadera desarmada de nuestro personaje también necesita una conexión de señal para decirle al personaje que inflija daño desarmado Conseguir a los padres de la Caja Hurtada y decirles que sufran un daño y proporcionarles la dirección normalizada. Luego en el guión del personaje, cuando creamos la instancia de arma, podemos establecer su daño para que sea el mismo número del recurso. I. Mientras estamos aquí, escribamos también la función de tomar daño en la región de combate. Aceptando una cantidad de daño a tomar, así como la dirección de la que proviene el daño, dándole un valor predeterminado de vector 30. Para recibir daños, nuestros personajes necesitarán salud. Voy a añadir una categoría de exportación para las variables de combate. Después declararé uno para los caracteres salud máxima como un entero, que estableceré en cinco. Y su salud actual también como un entero, que podemos establecer a su salud máxima usando add on ready. También declaremos un par de parámetros booleanos para saber si el personaje está muerto o no, y si el daño que se está tomando se entregó desde atrás, y también tomemos una referencia al cuadro rt del personaje usando add on ready Al recibir daño, la salud actual del personaje se reducirá por la cantidad de daño recibido, pero no queremos permitir que vaya por debajo de cero. Entonces podemos usar la función max para configurarla a este cálculo o a cero, lo que sea mayor El booleano de detrás se puede establecer entonces en true si el producto de punto de la dirección de daño con el vector base de plataformas de caracteres hacia adelante es un Si la salud actual del personaje después recibir daño es cero, entonces morirán. De lo contrario, serán golpeados. Si bien la animación de muerte será automática, la animación de golpe puede ser manejada por el guión de árboles de animación, y le diremos si el daño recibido estuvo por debajo o por encima de cierto umbral. De esta manera, podemos cambiar la animación de golpe en función de la cantidad de daño recibido. También es posible que queramos rastrear la salud de un personaje o cuándo muere. Sería una buena idea transmitir ambos de esos eventos como señales. Declarando una señal para cada vez que cambia la salud del personaje, podemos usar un porcentaje de salud restante como argumento y otra señal para cuando muere el personaje Después emiten la señal de salud cambiada si reciben daño y la señal de dado si muere el personaje. Para calcular su porcentaje de salud restante, simplemente dividimos su salud actual por su salud MX. Pero como ambos valores son enteros, el resultado también será un número entero, por lo que sólo alguna vez resultará en cero o uno Habrá que lanzar al menos uno de ellos a flote primero antes de realizar la división, por lo que el resultado también será a flote Si ya no queremos que los personajes muertos se vean impactados por colisiones, también podemos establecer su capa de colisión en cero, su máscara de colisión en uno, lo que solo se verán afectados por el terreno y establecerán su propiedad monitoreable H rtbach También es posible que un personaje pueda ser golpeado o asesinado mientras realiza una acción. Por lo que también debemos hacer un seguimiento de qué acciones que se interrumpen pueden causar problemas y corregirlos en una función privada. Por ejemplo, probablemente deberíamos apagar todas sus cajas de cadera si se interrumpieron sus ataques, lo que también podemos hacer en una función separada, verificando si existen referencias a cada una antes de apagarlas. En el árbol de animación de personajes, vamos a querer que el personaje muera o sea golpeado para interrumpir y anular todas las demás animaciones. Dado que este árbol de mezcla ya está guardado como recurso, podemos eliminarlo del árbol de animación y reemplazarlo con una máquina de estados. En el mismo nivel raíz de la máquina de estado, comenzaremos con nuestras animaciones de muerte de personajes, ya que esas tendrán la máxima prioridad absoluta sobre todas las demás animaciones. Después agrega otra máquina de estado para las animaciones de hit. Pasaremos de golpe a muerte A si el personaje está muerto. Con un corto fundido cruzado. O alternativamente a la muerte B si también fueron golpeados por detrás dando esta prioridad poniéndola a cero. Puede que no sea necesario que nuestro personaje vuelva a pasar de estar muerto, pero no está de más agregar la transición con la condición de que no estén muertos. Dentro de la máquina de estado hit, haremos algo similar con las animaciones de hit y agregaremos nuestro árbol de mezcla como la animación predeterminada aquí. Habilitando las transiciones a las animaciones de éxito y volviendo al árbol de mezcla al final de sus animaciones. Con un fundido cruzado tanto dentro como fuera de las animaciones de éxito, Con la máquina de estado del árbol de animación actualizada, guardaremos como un recurso del proyecto. Le voy a nombrar animaciones de personajes. Y por última vez, cada personaje puede actualizarse para usar la nueva máquina de estado. En el guión Árboles de animación, necesitaremos una referencia a la reproducción del estado hit. Además, dado que actualizamos el formato del árbol, necesitaremos actualizar todas estas rutas de propiedad. Ahora accederemos al nodo blend obteniendo el nodo hit, luego el nodo blend tree, y finalmente, el nodo blend two inferior más superior. Dando una definición a la función get hit, podemos recibir el parámetro booleano como si el personaje está recibiendo o no un golpe ligero Después dígale al estado de golpe que viaje ya sea al golpe A si fueron golpeados a la ligera o golpe B si fueron golpeados más fuerte. Vamos a probarlo. Si golpeamos el esqueleto, reaccionan al ser golpeados a la ligera, equipando un hacha y atacándolos de nuevo. Ellos son golpeados más fuerte. Un tercer golpe y mueren, cayendo hacia atrás ya que fueron golpeados desde el frente. Podemos equipar el gran hacha, que he configurado para tener un daño de cinco y matar a otro esqueleto por detrás, y caen hacia adelante a medida que mueren. También sería bueno poder rastrear la salud del personaje del jugador en la interfaz de usuario. Agreguemos un nodo de control y lo llamemos medidor de salud. Lo voy a poner detrás de todo lo demás en la interfaz de usuario. Esto necesitará un texto directo para dibujar el borde, un color erecto como relleno, y otro texto directo si queremos un icono Voy a usar el marco deslizador delgado como la imagen del borde. Es muy grande, así que la escalaré a una cuarta parte de su tamaño. Y voy a usar icono, pequeño corazón lleno para el icono. Redimensiónelo y colóquelo donde se vea bien en relación con el borde Luego estableceré el color para el color ect para que coincida con el color del corazón, y estableceré su posición y dimensiones para llenar el calibre. Voy a restablecer su propiedad de tamaño, anclar esto a la esquina inferior izquierda. Al hacer clic y arrastrar sobre la propiedad size x del relleno, podemos ver cómo el calibre se puede ajustar fácilmente a cualquier porcentaje Al adjuntar un script al medidor de salud, podemos llamarlo medidor para reutilizarlo para cualquier otro medidor que podamos desear Tomaremos una referencia al color de relleno ret usando add on ready, y también declararemos una variable para mantener el tamaño punto x del relleno cuando el calibre esté completamente lleno, que es lo que se establece la propiedad size dot x cuando se carga por primera vez. Luego escribe una función pública llamada set value, aceptando un parámetro de porcentaje flotante. Todo lo que tenemos que hacer es establecer la propiedad size x del color t para que sea el porcentaje multiplicado por el tamaño máximo. Al conectar la señal de cambio de salud del personaje del jugador a la función de valor establecido de medidores, ahora rastreará automáticamente la salud del jugador Para probar el medidor de salud. Solo le diré al personaje que reciba dos daños cada vez que el jugador presione el botón de correr. Ahora podemos ver que el indicador de salud del personaje se agota, y el personaje muere cuando está vacío Luego restableceré la línea de toma de daños para que vuelva a correr. Ahora tenemos a nuestro personaje siendo golpeado y recibiendo daño de los ataques. Y la siguiente lección, vamos a permitir que los personajes eviten ser golpeados esquivando Te veré en la siguiente lección. 8. sobreexponer/sobreexposicion: Hola, amigos. En la lección anterior, permitimos que nuestros personajes fueran golpeados por ataques, sufrieran daños y murieran. En esta lección, los ayudaremos a evitar daños esquivando. Comencemos en la configuración del proyecto, la pestaña Mapa de entrada, agregando un evento de entrada para esquivar Usaré la barra espaciadora o el botón de la cara derecha de mi mando. En el script del jugador, podemos usar los mismos métodos que jump y attack para amortiguar la entrada de esquivar. En el guión del personaje, necesitaremos una variable para saber si el personaje quiere esquivar o no. Pero un esquivar no es sólo una simple entrada. También requiere una dirección como vector tres. En la región de combate, necesitaremos una función de esquivar y una función de cancelación de esquivar, estableciendo la variable booleana Y con cualquier entrada en búfer, todas las demás entradas en búfer se establecerán en false. Como ya estamos almacenando la dirección de entrada en el guión de caracteres, podemos verificar si ese es el vector 30 en el momento en que se le dijo al personaje que esquive. Si no da ninguna entrada, quiero que el personaje esquive hacia atrás. Voy a usar el vector directo de bases de plataformas de caracteres, multiplicándolo por uno negativo para Si estamos dando entrada direccional, quiero que el personaje esquive en esa dirección, pero siempre con toda su fuerza. Normalizaré la dirección para eliminar la magnitud de la ecuación. En la máquina de estado de árbol de animación de personajes, navegando a través de la muerte y golpear animaciones en el árbol de mezcla, y finalmente, la máquina de estado de movimiento. Podemos agregar las animaciones de esquivar en un espacio de mezcla bidimensional. Transición de locomoción a esquivar si el personaje quiere esquivar, y de vuelta a locomoción al final de la animación Ambos con un desvanecimiento cruzado. Dado que esto se está conectando a la locomoción, el esquivar solo se realizará mientras el personaje esté en el piso También es posible que desee tener esquivas aéreas conectadas al estado de salto inactivo Dentro del espacio de mezcla de esquivar, cambiaré el ajuste de cuadrícula a factores de uno Después agrega las animaciones Dodge adelante, Dodge hacia atrás, Dodge izquierda y Dodge hacia atrás, Dodge izquierda y esquivar a la derecha que se mezclarán para que el personaje pueda esquivar en cualquier dirección. El script del árbol de animación tendrá que ser capaz de establecer la cantidad de mezcla de este espacio de mezcla como un vector dos, la misma manera que establecemos la cantidad de mezcla de las animaciones bloqueadas en estrafing De vuelta en el guión del personaje, al decirle al personaje que esquive, podemos decirle a la animación que establezca esta cantidad de mezcla. Pero la dirección de esquivar es un vector tres en el espacio global, mientras que la cantidad de mezcla para la esquiva es un vector dos en el espacio local de las plataformas de personajes Podemos calcular la cantidad de mezcla comparando la dirección de esquivar con los vectores de espacios de plataforma usando un producto de punto. Voy a necesitar invertir la cantidad de mezcla x multiplicándola por una negativa Si probamos esto, la animación de esquivar reproduce tres veces y el personaje en realidad no se mueve. La animación se repite porque quiere esquivar es cierto por un segundo completo, pero la animación tiene sólo 0.4 segundos de duración. Por lo que se repetirá tantas veces como pueda hasta que la variable quiere esquivar se ajuste de nuevo a false antes de que el 1 segundo esté arriba. Tendremos que establecer la variable false una vez que la esquiva se haya realizado con éxito y también aplicar algo de velocidad para mover al personaje. Añadiendo otra función, al igual que aplicar velocidad de salto, aplicaremos dodge velocity y llamaremos a esta función desde la animación. Si se llama a esta función, el carácter ha esquivado con éxito, y podemos establecer la variable en false para evitar que se produzcan más esquivas desde una sola entrada Después estableceremos la velocidad del personaje para que sea la dirección de esquivar multiplicada por la fuerza Dodge. Esto creará un impulso repentino de velocidad, moviendo al personaje rápidamente en la dirección en la que están esquivando Crear otra variable exportada para la fuerza de esquivar del personaje. Lo pondré en ocho. También puede querer que nuestro esquivar tenga marcos oculares, abreviatura de marcos de invencibilidad Esta es una duración de tiempo en la que el personaje no puede ser perjudicado por ataques Así como tenemos una función llamada por nuestras animaciones de ataque para activar o desactivar la caja de cadera, también tendremos una función llamada por las animaciones de esquivar para activar y desactivar la caja Hurt. Deberíamos usar set deferred para establecer la propiedad monitoreable de la caja Hurt al valor de active en caso de que esto ocurra durante un evento Ya que es posible que queramos llamar a esta función como resultado de una colisión y no podamos encender o apagar los colisionadores mientras se están procesando En las animaciones de personajes, necesitaremos agregar pistas de llamadas a funciones a cada una de nuestras animaciones de esquivar personajes. Primero apagaré la caja Hurt del personaje. Entonces cuando el personaje parezca que empieza a moverse en la animación, voy a aplicar la velocidad de esquivar. Una vez que hayan tenido tiempo para la velocidad de Dodge mueva al personaje fuera del camino del ataque, volveré a encender la caja de HRT cambiando el argumento a true Después repitiendo el mismo conjunto de llamadas de función para cada una de las animaciones de esquivar. Si bien no debería suceder con este código tal como está actualmente, podría ser posible que el personaje interrumpa mientras esquiva, lo que significa que el het box podría nunca ser reactivado Dependiendo de cómo funcione el juego, es posible que desee incluir la activación de la caja del personaje en las acciones de interrupción. Ahora que se está aplicando la velocidad de esquivar, realmente no me gusta cómo la animación de esquivar mueve realmente la posición raíz de las plataformas del personaje, lo que resulta en algunos movimientos abruptos, tanto conduciendo como saliendo del Entonces abriendo las animaciones, eliminaré los fotogramas clave raíz de las animaciones de esquivar. Mantener la plataforma de personajes arraigada donde el personaje debe estar según lo determinado por la física del cuerpo del personaje. Y luego repetiré esto también para las otras animaciones de esquivar. Ejecutando el juego, podemos ver el árbol de escenas remotas, encontrar la caja rt del personaje y prestar atención a la propiedad monitoreable Esquivar establece la propiedad monitoreable en false, luego la restablece a true, y el personaje anima la esquiva más suavemente con la velocidad gracias a la eliminación de los fotogramas clave raíz Con el esquivar ahora animando y funcionando correctamente, consideremos ahora si queremos permitir que el personaje ataque y esquive al mismo tiempo Además, ¿se debe permitir que el personaje ataque o esquive si está siendo golpeado? Si no queremos permitir este comportamiento, tendremos que rastrear cuándo el personaje está atacando, esquivando o siendo golpeado Vamos a agregar algunas variables booleanas más a nuestro script de personajes que está atacando, es esquivando y es Todos estos deberán exportarse para que sean accesibles al nodo del reproductor de animación. Usando pistas de propiedad, las animaciones de hit pueden establecer la variable is hit en true al inicio de la animación. Y volvamos a falso al final. Después en el árbol de animación, al hacer la transición de la locomoción a la esquiva, podemos verificar para asegurarnos de que el personaje quiera esquivar y nada es golpeado, y nada está atacando . Antes de pasar a cualquier estado de ataque, podemos comprobar no sólo si el personaje quiere atacar, sino también si no son golpeados y no esquivando Luego podemos repetir el proceso de establecer las variables booleanas en las animaciones de esquivar Cada uno que establece la variable está esquivando a true al inicio y false al final Nuevamente, con cada animación de ataque, establecer la variable is attack a true al inicio de las animaciones de ataque y cae al final. En caso de que se interrumpan ataques o esquivas, también deberíamos volver a establecer estas variables en false También existe la posibilidad de el personaje muera interrumpiendo la exitosa animación Así que vamos a establecer la variable is hit en false aquí. Para que la variable está atacando sea establecida por la máquina de estado de acción, también necesitaremos habilitar el filtro para ella y también la posición del hit box. Para probar si el esquivar realmente está funcionando, necesitaremos que los enemigos comiencen a atacar. Si aún no has configurado las animaciones de ataque enemigo, una manera fácil de hacerlo es copiar al jugador de animación de personajes y pegarlo en la escena enemiga. Entonces podemos decirle al árbol de animación que use el nuevo reproductor de animación. Y mientras el enemigo tenga la misma estructura ósea que el personaje, todas las animaciones funcionarán igual. De lo contrario, deberás configurar al enemigo para que tenga al menos un ataque capaz de activar una caja de cadera, enmascarando la caja t del personaje. Para hacer el ataque del enemigo, solo les voy a adjuntar un nodo en blanco en la escena de nivel. Con un guión sencillo, diciéndoles que ataquen. Haré una nueva carpeta para guiones enemigos y la llamaré ataque. Después de agarrar una referencia al personaje como padre de este nodo, le diré al personaje que ataque en la función ready Dado que la variable nunca volverá a ser falsa, esto es todo lo que se requiere para que los enemigos realicen ataques sin cesar Intentemos ejecutar el juego con formas visibles de colisión encendidas. Y ver el árbol de escenas remoto donde podemos ver los valores de todas nuestras nuevas variables. El personaje esperará a que termine un ataque antes de realizar una esquiva y viceversa. Si dejamos que el esqueleto golpee al personaje, reciben daño y no pueden atacar o esquivar hasta que termine la animación de golpe. Y podemos esquivar el ataque del esqueleto con nuestra nueva acción esquivadora Ahora tenemos a nuestro personaje esquivando para evadir ataques y restringiendo cuándo el personaje puede realizar En la siguiente lección, permitiremos que los personajes bloqueen los ataques entrantes con un escudo. Te veré en la siguiente lección. 9. Bloque: Hola, amigos. En la lección anterior, ayudamos a nuestros personajes a evitar recibir daños esquivando ataques En esta lección, les permitiremos bloquear ataques con un escudo. Comencemos en la configuración del proyecto, la pestaña Mapa de entrada y agreguemos un evento de entrada para bloquear. Usaré el botón derecho del ratón y el botón del hombro izquierdo en mi mando. En el guión del jugador, el botón de bloqueo no necesita ser búfer, ya que se comporta más como el botón de ejecución, cambiando el comportamiento del personaje mientras se mantiene pulsado el botón Enviar una señal al personaje para bloquear o no, en función de si se presiona o suelta el botón. El script de caracteres puede entonces almacenar este valor en una variable. Quiere bloquear. Pero a diferencia de las otras variables, no hay necesidad real de almacenar en búfer la entrada de bloqueo. Después agrega una función en la sección de combate que establece esta variable. En el árbol de animación de personajes máquina de estado navegando a la máquina de estado de acción. Podemos agregar la animación de bloques y hacer la transición a ella si el personaje quiere bloquear con un corto fundido cruzado. Después la transición de nuevo a si no quieren bloquear. Al obtener una visión del personaje y fusionarse en el estado de acción, esta animación hace que el personaje levante su escudo. Una vez que se completa esta animación, podemos hacer la transición a la animación de bloqueo, que debe establecerse en bucle para mantener el escudo alto siempre el jugador mantenga presionado el botón de bloqueo. Esto también volverá a inactivo si el personaje ya no quiere bloquear con un corto fundido cruzado. También podríamos querer poder hacer la transición a la animación de bloques desde algunos de nuestros otros estados inactivos, como los estados inactivos desarmados y de una mano Para mantener el número de transiciones más bajo, primero combinaré los estados inactivo y inactivo de una mano combinando lógicamente las condiciones de transición para alcanzar el estado de ataque con una mano Si la animación de ataque es una, quieren atacar y no son golpeados y no esquivando Después, regresa al ralentí al final de la animación de ataque. Eliminando el estado inactivo de una mano, luego reorganizaré los otros estados para que estén un poco más organizados Ahora, ya sea un ídolo inactivo o desarmado puede pasar a bloquear, si el personaje quiere bloquear, y hacer la transición directamente de nuevo a desarmado, si la animación de ataque del personaje es cero, y o bien tienen un objetivo o quieren atacar, y no quieren Con una prioridad de cero. Ahora bien, ya sea inactivo o inactivo desarmado puede pasar a bloquear si el personaje quiere bloquear Los estados de bloqueo y bloqueo pueden saltar inactivo y regresar directamente a inactivo desarmado con una prioridad de cero De esta manera, el personaje no tiene que pasar por dos estados de inactividad diferentes entre el bloqueo y el ataque. Si lo probamos, nuestro personaje puede hacer la transición a la animación de bloque al presionar el botón de bloqueo y volver a estar inactivo cuando se suelta el botón de bloqueo. Pero tendría más sentido restringir al personaje para que solo use esta animación si tienen un escudo equipado. Para ello, necesitaremos otro script de recursos. Heredando del equipo, dándole un nombre de clase de escudo Si quieres que tus escudos tengan diferentes variables, podemos definirlos aquí. Agreguemos una variable por la cantidad de daño reducido al bloquear con este escudo con un valor predeterminado de uno. Acceder al recurso personalizado de escudos redondos bárbaros. Podemos cambiarlo para que sea un escudo y cambiar la cantidad de reducción de daño si queremos. Recuerde repoblar las propiedades que se restablecen como resultado de este cambio de clase, y actualice todos los escudos para usar el nuevo script de clase En la escena del escudo, tendremos que poder almacenar las variables del recurso de objeto en el escudo tal como hicimos con el arma. Añadiendo un nuevo script, solo tendrá una variable entera de reducción de daño y una función ficticio activar hip box, que ignorará el argumento booleano y Quedará claro por qué esto es necesario en un minuto. Entonces podemos reemplazar el guión adjunto a nuestro escudo por el nuevo. En el guión del personaje, agreguemos otra variable a la categoría de equipo para saber si el personaje tiene o no un escudo equipado. Al ponerse una pieza de equipo, si el objeto es un escudo, entonces lo configuraremos para que sea el equipo fuera de mano, pasaremos el valor de reducción de daño del recurso del objeto al escudo, y set tiene escudo equipado a true Dado que la variable off hand ahora sostiene un escudo en lugar de un arma, interrumpir las acciones del personaje desactivará todas las cajas de cadera Y como el off hand no es nulo, le estamos diciendo que desactive su caja de cadera Pero le hemos dicho al escudo que haga caso omiso de esta petición. Entonces al quitarse una pieza de equipo, si el socket es el offhand, entonces podemos suponer que el personaje ya no sostiene un Entonces al decirle al personaje que bloquee, podemos agregar la condición de que el personaje también debe tener un escudo equipado. El guión de inventario también necesitará algunas condiciones más a la hora de equipar un escudo también para evitar que el personaje equipe un escudo cuando su mano fuera ya está ocupada con un arma a dos manos o fuera de la mano Este proceso variará dependiendo cómo funcionen sus sistemas de inventario y equipos. Si el elemento seleccionado es un escudo, y el personaje tiene algo equipado en su mano principal, y el personaje actualmente está usando las animaciones de dos manos o de doble rueda, Entonces desequiparé la toma de mano principal y le diré al personaje que dof el equipo en su mano principal Si lo probamos. Ahora se ignora el botón de bloqueo si el personaje no tiene un equipo de escudo. Podemos equipar un arma a dos manos, luego equipar el escudo. El arma a dos manos se desequipa automáticamente, y luego se equipa el escudo Y ahora el personaje puede bloquear con el escudo. A continuación, consideremos cómo funciona la entrada de bloqueo con nuestras otras acciones. Si el jugador está bloqueando y decide atacar o esquivar, entonces me gustaría que esas acciones tomen prioridad interrumpiendo el bloqueo Pero si solo establecemos la variable wants to block en false, entonces el jugador tendrá que soltar el botón de bloqueo y volver a presionarlo para continuar bloqueando. En su lugar, podemos declarar otra variable booleana. Vamos a llamarlo bloque de interrupción. Si el personaje quiere atacar o esquivar, entonces esta variable se puede establecer como verdadera. Y cuando termine el ataque o esquivar, podemos volver a establecerlo en falso para permitir que el personaje continúe bloqueando automáticamente. Simplificaré la función add dodge velocity para simplemente llamar cancel dodge. Después en el árbol de animación, podemos agregar las condiciones para la transición fuera del bloque o el bloqueo para incluir si el bloque está siendo interrumpido. Y no permitir que las transiciones vuelvan a bloquearse hasta que el bloque ya no esté siendo interrumpido. Ahora el personaje dejará de bloquear mientras ataca y automáticamente volverá al bloqueo siempre y cuando el botón de bloqueo siga presionado. Y lo mismo también funciona para esquivar. Lo último que tenemos que hacer es reducir en realidad el daño de los ataques entrantes mientras se bloquea. Para ello, necesitaremos saber si el personaje está bloqueando. Dado que el bloqueo no se limita a una sola animación y los bucles de animación, no hay forma de que podamos simplemente decirle al animador que establezca una variable booleana en true o false Vamos a agregar la animación de golpe de bloque. Habilitando la transición a esta animación de bloquear y regresar al final de la animación. Lo que contratamos para saber si el personaje está bloqueando es en qué estado se encuentra actualmente esta máquina de estado. Si está en el estado de bloqueo o golpe de bloque, entonces el escudo del personaje está arriba. La animación de bloques también es bastante larga. Incluye no sólo levantar el escudo, sino también un ciclo de animación de bloqueo. No creo que se deba considerar que el personaje bloqueando hasta después de que el escudo esté completamente levantado, pero tampoco quiero esperar a que termine la animación de bloques. Entonces, en el reproductor de animación del personaje, voy a reducir la longitud de la animación de bloque para que se detenga después de que el escudo se levante a un tercio de segundo. En el script de árboles de animación, agreguemos una función pública para verificar si el carácter está bloqueando, devolviendo un booleano Primero, almacenar el nombre de los estados de acción nodo actual en una variable de cadena. Podemos regresar si es bloqueo o golpe de bloqueo. Y también necesitaremos otra función para reproducir la animación de golpe de bloque, diciéndole al estado de acción que viaje al estado de golpe de bloque. Después en el guión del personaje, en la parte superior de la función take damage. Podemos comprobar si la animación del personaje está bloqueando actualmente, y que la dirección de la que proviene el daño es el frente del personaje. Usando un producto de punto de la dirección del daño con el vector base de plataformas de caracteres hacia adelante Si el valor es un número positivo, entonces el daño viene de algún lugar frente a ellos. Sin embargo, esto cubriría un gran ángulo, una media esfera completa frente al personaje. Usando algo más cercano a un cuarto o medio, podemos limitarlo a una forma de cono. En estas condiciones, el ataque debe ser bloqueado con éxito, reduciendo la cantidad de daño por la reducción de daño del escudo. Usando la función max para limitarlo a un mínimo de cero. Entonces podemos decirle al árbol de animación que reproduzca la animación de golpe de bloque, y si la cantidad de daño se ha reducido completamente a cero, solo regresaré ya que el personaje no está recibiendo ningún daño. Vamos a probarlo. Equipando el escudo y bloqueando el ataque del esqueleto El daño se reduce a cero y se reproduce la animación de golpe de bloque. Al recibir daño desde el costado o la espalda, el personaje aún recibe daño. Ahora tenemos a nuestro personaje capaz bloquear ataques con un escudo desde el frente. En la siguiente lección, les daremos un arma a distancia que pueda disparar proyectiles Te veré en la siguiente lección. 10. Rodaje: Hola, amigos. En la lección anterior, permitimos que nuestro personaje bloqueara ataques con un escudo. En esta lección, les daremos arma arreglada capaz de disparar proyectiles Este paquete de activos no contiene un perno para la ballesta, así que comenzaré haciendo uno en la escena de la ballesta Comenzando con un cuerpo rígido de tres nodos D , renombrándolo perno Lo colocaré donde descansará la base del cerrojo dentro de la ballesta con su vector base z azul apuntando hacia adelante donde estará disparando A continuación, voy a añadir una instancia de malla tres nodo D como hijo, poblándolo con la malla del cilindro Reduciendo el radio y la altura, girándolo para apuntar hacia adelante y posicionarlo hacia adelante a lo largo del eje z. Sólo le daré un material básico y pondré el albedo para que sea de color marrón Después agregue un nodo básico de tres D como otro hijo, por lo que se colocará con la misma posición y rotación y renombrarlo amo socket. Entonces reparent amo socket a la ballesta conservando esta posición y rotación Reparar el perno al zócalo amo, por lo que su posición y rotación relación con su padre ahora es cero El cerrojo ahora se puede convertir en su propia escena, que pondré en una nueva carpeta para proyectiles, y luego lo eliminaré de la escena de la ballesta La ballesta ahora se puede cargar simplemente agregando un cerrojo como hijo de este nodo El perno necesitará una forma de colisión. Voy a usar una cápsula con las mismas dimensiones y posición que el cilindro. Ampliando la sección del solucionador, necesitaré tener habilitado el monitor de contactos y establecer los contactos máximos en algo mayor que cero Si queremos que el cerrojo colisione con el terreno, necesitará enmascarar la capa de colisión uno Y quiero que mis tornillos se muevan lentamente para poder ver lo que están haciendo. Pero no quiero que caigan por gravedad. Entonces pondré su escala de gravedad a cero. Adjuntando un script al perno, podemos nombrarlo proyectil, por lo que puede ser utilizado para otro tipo de proyectiles en nuestro juego y guardarlo en la carpeta de scripts de elementos Tan pronto como se instancie un cerrojo, se cargará en la Y es posible que queramos pasar información del personaje o arma a las municiones en este momento. Vamos a crear una función pública para hacer eso. Pero por ahora, solo pondremos verdad su propiedad de congelación ya que el cuerpo rígido no necesita hacer nada hasta después de que se dispare el arma. Para disparar el proyectil, aplicaremos una fuerza de impulso enviada por el arma como vector tres En este momento, el cuerpo rígido puede comenzar aplicar física para mover el perno a través de la escena del juego, estableciendo su propiedad de congelación en false. Ya no queremos que el proyectil siga las propiedades de transformación de su padre, la ballesta Debe volver a ser apaciguada a la escena del juego donde pueda moverse y actuar libremente En caso de que no esté apuntando directamente hacia la dirección, se está disparando, podemos decirle al cerrojo que mire un punto en el espacio que es su propia posición global menos la dirección de la fuerza de impulso. Después aplique la fuerza de impulso al perno para que se mueva en esa dirección. Conectando la señal ingresada del cuerpo rígido al guión, se llamará a esta función si el cerrojo hace contacto con algo en la capa de colisión uno, el terreno. Si eso sucede, el cerrojo puede permanecer exactamente donde hizo contacto, estableciendo su propiedad de congelación de nuevo en true, pero diferido ya que esto sucede durante una colisión Es muy importante que cada vez que implemente una función en un juego que instancie una gran cantidad de nodos, que también implemente alguna forma de limpiarlos. De lo contrario, podrías terminar con cantidades muy grandes que hacen que las velocidades de fotogramas bajen y eventualmente bloqueen tu juego. Una práctica común con los proyectiles es solo darles una vida útil máxima Vamos a agregar un nodo de tiempo a nuestros proyectiles y configurarlo para que cuente atrás una Lo pondré a 10 segundos. Luego toma una referencia a la hora o nodo usando add on ready. Iniciaremos el temporizador al disparar el proyectil. Si no termina golpeando nada, todavía queremos limpiarlo, que no se limite a volar a la distancia para siempre. Conexión de la señal de tiempo arriba a la secuencia de comandos del proyectil. Señalará que el proyectil se libere de la escena del juego De vuelta a la escena de la ballesta, necesitaremos un nuevo guión para esta arma Podemos nombrarlo arma a distancia y ponerla en la carpeta de scripts de elementos Sustituir el guión que se adjunta a esta arma por arma a distancia y darle una referencia al archivo de recursos personalizado para la ballesta Podemos exportar la munición como una escena empaquetada, una prefabricada que podemos usar como plano para instanciar tantas como necesitemos Después asigne el cerrojo como munición para la ballesta en el inspector Necesitaremos una referencia a la toma de munición usando at on ready y una referencia a la munición que actualmente está cargada en el arma a distancia También podría ser bueno tener una bonificación de daño que el arma agregará a los disparos que se le disparen como un entero. La cantidad de fuerza de impulso que el arma aplica a su munición cuando se dispara a flote Usaré un número bajo como diez para que podamos ver los pernos moviéndose por el aire fácilmente, y la máscara de colisión de nuestros enemigos para que la información pueda pasar del personaje th el arma a la munición. Al equipar el arma, personajes están configurando la caja de cadera, máscara de colisión de armas, por lo que podemos reutilizar fácilmente la misma función para establecer la variable máscara Y al igual que hicimos con el escudo, podemos agregar una función para activar la caja de cadera, ignorando este parámetro, y simplemente regresar Ya que el arma no tiene caja de cadera propia. El arma necesitará poder disparar el proyectil con una función pública, y dejaremos que el personaje especifique la dirección en la que quiere que vaya el proyectil como parámetro Todo lo que el arma necesita hacer es pasar esta llamada de función al amo, multiplicando la dirección por la fuerza armamentista Después establece la referencia amo cargada null ya que el arma ya no está cargada, y una función de recarga, que instanciará un nuevo perno, asignándolo Después agrégalo como niño del zócalo amo, dándole la posición correcta y rotación requerida para que se asiente bien en la ballesta Entonces podremos pasar cualquier información que la munición necesite saber antes de que se dispare, como el daño de las armas y la máscara de colisión. Entonces, sigamos adelante y agreguemos estos como parámetros a la función de onload en el script del proyectil Nuestro guión de personaje necesitará una variable para saber si el arma que tienen está cargada actualmente. Y dos nuevas funciones, recargar y disparar. Recargar, solo establecerá la variable en true, y luego le dirá al arma de mano principal que se recargue Por ahora, disparar solo establecerá la variable en false, luego le dirá al arma principal que dispare en una dirección, pasando las plataformas de personajes hacia adelante vector base Si el arma no está equipada, ya que se está retirando completamente del árbol de escenas, también se retirará la munición junto con Así que voy a resetear el arma se carga variable de nuevo a falso en este punto. Nuestra enumeración de tipos de armas, necesitaremos dos entradas más para el rango de ataques con una mano, que será el número cuatro, y los ataques de alcance a dos manos es el número cinco En el recurso personalizado ballestas, voy a cambiar el guión de equipo a arma Cambiaré su tipo de arma al alcance de una mano, bajaré su daño y volveré a poblar su icono Y de igual manera cambiar la ballesta pesada a rango de dos manos En el árbol de animación de personajes, necesitaremos más acciones para los ataques de rango. Esta máquina de estado ya se está volviendo bastante grande y desordenada, así que envolveré los ataques de alcance dentro de otra máquina de estado Al hacer la transición a esta máquina de estado, si la animación de ataque de los personajes es de cuatro o cinco, y quieren atacar, y no son golpeados y no esquivando Después vuelve al ralentí al final de la animación. Y voy a mezclar ambas transiciones con un poco de fundido cruzado. Dentro del rango para atacar la máquina de estado, podemos agregar animaciones para disparar y recargar. Tanto para ataques a distancia con una mano como a dos manos. Solo necesitamos jugar el correcto una vez y luego salir de nuevo a la máquina de estado de acción. Entonces todos harán la transición al final. Las transiciones a una mano requerirán que la animación de ataque se establezca en cuatro. Y a dos manos establecido a f. si el tiro o recargar animaciones jugar se basará en el valor de arma se carga Ahora que las animaciones pueden ser reproducidas por el árbol de animación, necesitamos las animaciones para llamar a funciones en el guión del personaje. Durante la animación de disparo, agregaremos un método llamado track and scrub al fotograma antes de que el personaje retroceda del proyectil que se está disparando Luego agrega un fotograma clave para llamar a la función de disparo. Asimismo, durante la animación de recarga, intentaremos seleccionar un fotograma cuando el personaje haya terminado de recargar el arma Y agrega un fotograma clave a la pista del método de llamada para recargar realmente el arma Si queremos que estas animaciones bloqueen al personaje para que no pueda realizar otras acciones, tendremos que establecer una variable booleana como hicimos con los ataques Sólo voy a reutilizar la variable está atacando. Y repita también para las animaciones a distancia a dos manos . Vamos a probarlo. Podemos equipar la ballesta al personaje, y presionando el botón de ataque una vez, haremos que carguen la ballesta con un perno Al presionar el botón de ataque por segunda vez, disparan la ballesta hacia adelante, y el cerrojo dispara hasta que golpea algo en el ambiente, donde se detiene y se destruye después de 10 Ahora necesitamos los tornillos para infligir daño a los enemigos. De vuelta en la escena del cerrojo, necesitaremos agregar una caja de impacto al perno. La caja de impactos necesita una forma de colisión. Voy a usar la esfera. Lo colocaré en el otro extremo del perno y le daré un radio menor. Al igual que nuestras otras cajas de cadera, no necesita estar monitoreando ni tener una máscara de colisión todavía. Agarrando una referencia a la caja de cadera usando en listo, también exportemos una variable para el daño de los pernos. Voy a usar un valor predeterminado de uno. Cuando el personaje carga el cerrojo en la ballesta, esa sería una buena oportunidad para transmitir información, como cualquier bono de daño y la máscara de colisión La bonificación de daño de armas se puede agregar al daño de los pernos, y la capa de colisión de la caja de cadera se puede establecer en la capa de colisión enemiga del personaje. Cuando se dispara el proyectil, podemos decirle a la caja de cadera que comience a monitorear cajas de rebaño enemigas. Conectando el área de la caja de cadera ingresó la señal al guión del proyectil Podemos decirle a la caja Hurt que este proyectil impactó para decirle a su personaje padre que reciba daño. Desde la dirección de las cajas Hurt posición global menos la posición global de Bolt normalizada. El perno puede ser entonces para ser removido de la escena. Y si el cerrojo golpea el terreno, ya no debería estar monitoreando para infligir daño, así que lo pondremos en falso diferido En el guión del personaje, me gustaría asegurarme absolutamente de que cuando el personaje está bloqueado en un objetivo, el proyectil se dispara directamente contra ese objetivo Por lo que la función disparar se dividirá en dos comportamientos diferentes en función si el personaje está bloqueado o no en un objetivo, llamando a una función separada para disparar a un objetivo, pasando el objetivo como argumento. Pero el arma solo debería disparar al objetivo de encierro si el personaje se enfrenta a ellos. Así podemos verificar si el producto punto del carácter rigs forward basis vector y la diferencia normalizada en sus posiciones globales es un número positivo Cuanto más cerca de lo positivo es esto, cuanto más similares son, más se enfrenta el personaje hacia ellos. Diré que algo más grande que 0.75 está lo suficientemente cerca como para disparar al objetivo del encierro. En el guión de arma a distancia, dando una definición a disparar al objetivo, aceptando un objetivo como parámetro Ahora podemos calcular la dirección como la diferencia de posiciones de gulple normalizada y multiplicada por la fuerza Dado que esto utilizará la posición de gubal de armas, no la posición de gubal del personaje, la dirección será más precisa Y voy a sumar 1 metro hasta la posición del objetivo para no apuntar a sus pies. Vamos a probarlo. Equipando un arma a distancia y bloqueando un objetivo, primero me enfrentaré a un lado, y el proyectil aún dispara hacia adelante, ya que el personaje no está mirando hacia el Moviéndose para enfrentar al objetivo y disparar un segundo perno, esta vez dispara directamente al objetivo e inflige daño. Ahora tenemos proyectiles disparados desde armas a distancia, golpeando a los enemigos o En la siguiente lección, permitiremos a los enemigos detectar jugadores y contraatacar. Te veré en la siguiente lección. 11. Enemigo: Hola, amigos. En la lección anterior, agregamos ataques de alcance que disparan proyectiles En esta lección, permitiremos que los enemigos detecten, persigan y ataquen al personaje del jugador. En la escena del cementerio, agregamos un simple nodo que le dice al enemigo que ataque constantemente Eliminemos eso y comencemos a construir una versión más compleja para atacar solo cuando el personaje del jugador esté en rango para ser golpeado. En la escena de esbirros esqueleto, le agregaremos un nodo hijo de tipo nodo tres D, ya que necesitará acceder a tres posiciones D y rotaciones Voy a llamarlo agresión. Después agrega un nodo D de área tres, que representará el alcance de ataque del enemigo. Le daré forma de colisión y usaré una esfera. Ajustando el tamaño de la esfera para que sea un poco más grande, le daré un radio de 1 metro, luego la colocaré para que quede 1 metro arriba del suelo y 1 metro adelante. El área de alcance de ataque estará monitoreando las colisiones que enmascaren la caja del rebaño del jugador. L et's adjuntan un script a este nodo y lo ponen en la carpeta de scripts enemigos. Dado que el propósito de este script es controlar un personaje al igual que el nodo del controlador de entrada del jugador, necesitaremos una referencia al personaje que está siendo controlado por este nodo Con la forma en que estoy estructurando mi árbol de escenas, este nodo siempre será el hijo directo del nodo de carácter, para que pueda acceder al personaje llamando a get parent. Conectando las señales de área ingresada y área de salida al script, renombraré los parámetros y les daré tipos para mayor claridad Cuando los personajes del jugador Herir caja entra en el rango de ataque, queremos decirle al enemigo que ataque. Y cuando la caja Hert salga del rango de ataque, podemos decirle al enemigo que no ataque Podemos guardar esta rama como escena propia y guardarla en la carpeta de escenas enemigas. Entonces elimínelo de esta escena enemiga. E De vuelta en la escena del cementerio, podemos unir nuestro nodo de agresión enemiga a cualquiera o a todos nuestros enemigos para que ataquen automáticamente al personaje del jugador si entran en el rango de ataque Vamos a probarlo. Los enemigos aún no están atacando, pero atacaremos si entramos en su rango de ataque y nos detenemos cuando lo dejamos. A continuación, permitiremos que los enemigos vean al personaje del jugador desde una distancia adicional. Al abrir la escena del nodo de agresión, podemos agregar otra área tres nodo D para representar la visión de un enemigo. Añadiendo una forma de colisión a esta escena, usaré otra esfera con un radio mucho mayor. Utilizaré 5 metros y lo colocaré para estar por delante del enemigo y un poco arriba del piso. Esta área puede estar monitoreando la capa de colisión del personaje del jugador. Voy a usar la capa nueve. Después agregue un rayo fundido tres nodos D para que sea su línea de visión y también mueva esto hacia arriba del piso. Esto estará buscando la misma capa que el campo de visión, pero también ser obstruido por el terreno Ya que usé la capa nueve, que es el cuerpo del personaje y no la caja t, conectaré las señales de on body ingresadas y salidas al guión de agresión Cuando un cuerpo entra al campo de visión, lo guardaré en una variable, Vamos a llamarlo objetivo de tipo personaje cuerpo tres D. Pero también tendremos que confirmar que también tienen una línea de visión clara antes de volverse agresivos. Entonces necesitaremos una referencia al elenco. Y podemos almacenar si el enemigo ha visto o no al jugador en una variable booleana Tomemos también ahora también una referencia al campo de división del enemigo. A. Montando la función de proceso, podemos comenzar comprobando si se ha establecido el valor de target. Si es nulo, entonces el enemigo no puede ver al personaje del jugador. Deberíamos simplemente regresar. Si el enemigo aún no ha visto al jugador, entonces podemos verificar su línea de visión al objetivo. Establecer la posición objetivo del raycast para que sea la diferencia en sus posiciones globales, sumando un metro arriba del suelo Después de forzar al raycast a actualizarse si está colisionando con algo y ese algo con lo que está colisionando es el objetivo, entonces la línea de visión no se ve obstruida Podemos establecer la variable has seen player en true. Si el valor de esta variable es verdadero, entonces el comportamiento del enemigo cambiará, y haremos que persigan al personaje del jugador. Cuando el personaje jugador sale del campo de visión del enemigo, si el cuerpo es el objetivo, y el enemigo aún no ha visto al jugador, entonces ya no necesitamos verificar su línea de visión, para que podamos establecer objetivo en nulo. Este nodo de agresión es hijo del nodo de carácter, que no está rotando. Por lo que el campo de visión y alcance de ataque no rotarán con la plataforma de personajes. Podemos usar la referencia de caracteres para agarrar la rotación de la plataforma, acceder a la propiedad y, y asignarla a esta rotación de nodos y Por lo que seguirá la misma rotación. También podríamos querer una manera de decirle a este enemigo que deje de perseguir al personaje del jugador. En cuyo caso, podemos establecer el target en null, ha visto target a false y decirle a este personaje que se mueva sin dirección. Un buen momento para llamar a esta función sería cuando muere el enemigo. Así que anulando la función ready. Podemos conectar la señal de muerte de este personaje a la función de parada. Cuando el enemigo ve por primera vez al personaje del jugador, también podemos conectar la señal de muerte de los objetivos a la función de parada para evitar que el enemigo intente matar al personaje del jugador después de que ya haya muerto. También usaré esta misma función para apagar la visión de este enemigo, estableciendo su propiedad de monitoreo en falsa. Para que el enemigo se mueva hacia el jugador, primero necesitamos hacer algunos cambios en nuestra escena de niveles. Vamos a agregar una región de navegación tres nodo D al nivel. Entonces re padre cualquier nodo que se utilizará para generar nuestro mapa de navegación como hijos de este nodo, incluyendo el suelo y los obstáculos. Con eso hecho, selecciona el nodo de la región de navegación y rellena la malla de navegación con una nueva malla de navegación Después haz clic en el botón Hornear malla de navegación. La malla de navegación cubrirá el terreno con triángulos que forman un área donde los personajes podrán caminar Ampliando el recurso de malla de navegación, podemos ver sus propiedades. El único apartado de preocupación en estos momentos es la sección de agentes. Los agentes son nuestros personajes que usarán esta malla de navegación para pasear por la escena. Echando un vistazo rápido a nuestras cápsulas de colisión de personajes, les he dado una altura de 2.6 metros y un radio de 0.75 metros. Copiaré esos valores en la altura y el radio de los agentes en el recurso de medición de navegación, luego volveré a hornear la malla de navegación La malla ahora deja más espacio de paredes y obstáculos. Para poder utilizar la región de navegación, todos nuestros caracteres necesitarán otro nodo adjunto a ellos, un agente de navegación tres nodos D. Asegúrate de adjuntar uno a cada personaje. Agarrando una referencia a este nodo usando add on ready. Luego podemos escribir una función en el script de caracteres, que puede usarse para decirle a cualquier personaje que navegue a cualquier ubicación en la malla de navegación por cualquier motivo. Esto también es muy útil para muchas cosas fuera del combate. Aceptando una posición objetivo como vector tres, estableceremos la posición objetivo del agente de navegación para que sea la misma ubicación. El agente de navegación utilizará automáticamente la malla de navegación, asignada la misma capa de navegación para producir una ruta para acercarse lo más posible a la ubicación de destino. llamar a los agentes obtener la siguiente posición de ruta, devolveremos el primer punto de camino a lo largo de esta ruta como un vector tres. Luego podemos restar la posición global actual del personaje para obtener un vector apuntando desde donde estamos a la primera posición a lo largo del camino Si multiplicamos esto por 101 para eliminar el componente vertical, entonces normalizamos este vector. Ahora es funcionalmente equivalente a un vector de entrada producido por nuestro script de manejo de entrada del jugador cuando el jugador inclina la palanca analógica o usa las teclas WASD Así podemos asignar esto a la variable de dirección de entrada. Y el proceso de física se encargará del resto, diciéndole al personaje que camine por este camino, que los llevará hasta su objetivo. Sería una buena idea trasladar todo lo que le sucede a un personaje cuando muere a una función pública en caso cualquier otra cosa que no sea recibir daños pueda causarle la muerte. Cuando un personaje muere, debemos decirles que dejen de moverse. Y cuando se les dice que se muevan o tomen alguna acción, debemos ignorar esas peticiones si el personaje está muerto al regresar. De vuelta al guión de agresión, solo necesitamos decirle al enemigo que navegue hacia su objetivo una vez que lo haya visto. Antes de probarlo, escojamos un enemigo. Voy a usar el guerrero esqueleto y seleccionar su navegación Agente tres nodo D. En la sección D Bug, haz clic en Activar Toggle para poder ver el camino renderizado en el juego. Al acercarse al primer esqueleto, cuanto entramos en su campo de visión, la línea de visión confirma de inmediato que pueden vernos, y el agente de navegación encuentra un camino para que el enemigo camine hacia nosotros. Entonces nos atacan. Derrotar a este enemigo, esta vez, llamemos la atención del pícaro Ya que están detrás de la lápida, no se confirma la línea de visión y el enemigo permanece escondido Y si nos acercamos al guerrero, podemos correr alrededor de la tumba abierta, viendo como el agente de navegación actualizará automáticamente la ruta en tiempo real, para recorrer el camino más corto posible para llegar al jugador. También podríamos querer que nuestros enemigos sean capaces de empuñar armas De vuelta en la escena del cementerio, vamos a unir otro nodo básico a uno de nuestros enemigos, y nombrarlo equipar Adjuntando un script a este nodo, lo pondré en la carpeta de guiones del enemigo. Todo lo que necesitamos hacer es tomar una referencia al nodo padre, al personaje, y exportar un arma para equipar a este personaje. Después en la función listo, dígale al personaje que haga el arma. Le diré a mi guerrero esqueleto que equipe un gran hacha. Entonces copia y pega este nodo sobre otro enemigo y cambia el arma por otra cosa. Le voy a dar unos cuchillos al pícaro. Cada una de nuestras escenas enemigas necesitará tener nodos de unión ósea agregados a ellas. Siguiendo su ranura para mano izquierda y ranura para mano derecha. Luego podemos poblar el conjunto de sockets de los equipos de personajes con estos nodos para ser utilizados al equipar armas Por último, sería bueno no tener que recargar el juego cuando morimos Así que vamos a conectar la señal de los personajes del jugador muerto al guión del manager del juego. Después de desvanecerse a negro, solo le diré al árbol de escenas que recargue la escena actual, restableciendo todo de nuevo a cómo era cuando se cargó la escena Vamos a probarlo. El guerrero esqueleto está equipado con la gran a y está utilizando las animaciones de ataque a dos manos. Cuando morimos, se recarga toda la escena. Y subiendo esta vez contra el pícaro, están equipados con los cuchillos y utilizan animaciones de doble rueda. Ahora tenemos un complejo sistema de combate en nuestro juego con una variedad de mecánicas que se pueden ajustar para adaptarse a las necesidades de tu juego.