a pesar que me lo sugiere vsc el if else que agregamos queda mejor con un operador binario:
currentSpeed = Mathf.Abs(Input.GetAxisRaw(horizontal)) && Mathf.Abs(Input.GetAxisRaw(vertical)) ? speed / Mathf.Sqrt(2) : speed
Introducción
Game Design del juego
La estructura y assets de un proyecto en Unity
Convirtiendo nuestros assets en Tiles
Tilemaps y creación del escenario
Bonus: FastForward de la creación del escenario, sorting layers y creación de colliders
Acá encontrarás los archivos de este curso
Personaje principal: Movimiento y Animaciones
El jugador y el movimiento
Creando nuestra primera animación
Creando el grafo de animaciones
Usando un árbol de animaciones
Mostrando la solución del desafío e implementando transición entre blended trees
Programando una cámara que siga al jugador
Corrección del bug gráfico
límites del escenario, rigid bodies
Ejercicio: diseño de interiores
Escenarios Avanzados
Transiciones entre escenas
Mantener Player y Camera entre escenas
Spawning Points: programando que el jugador y la cámara aparezcan en el lugar correcto al cambiar de escena
Agregando Identificadores a nuestros Spawning Points para controlar mejor el flujo de nuestro juego
Enemigos Avanzados
Creando nuestro enemigo
Programando las físicas y el patrullaje del enemigo
Generando movimiento completamente aleatorio
Programando el ataque del enemigo
Crear Manager de Health del Player
Crear armas
Programando el ataque del Player con arma
Mover la espada al caminar
Creando el ataque con espada
Ejecutando el ataque con un botón
Movimiento en diagonal
Optimizando nuestro player controller
Ataque mejorado
Uso de partículas
Añadir el daño del enemigo en batalla
Programando los contadores de vida del enemigo
Colocando más info de UI en pantalla
Script de la vida
Personaje principal avanzado
Añadir el daño del personaje (ejercicio)
Sistema de puntos de experiencia para nuestro personaje principal
Level Up!
Level Up! Defensa y Reto Final del Módulo: Stats de los enemigos
Creando un NPC
Limitar el movimiento de nuestro NPC
Creando una pantalla de diálogos para nuestro RPG
El diálogo del NPC
Múltiples líneas de diálogo
Parar el NPC durante el diálogo
Parar el personaje durante el diálogo
Quests
La estructura de una quest
Quest 1: Ir a un lugar
Quest 2: Encontrar un objeto
Quest 3: Matar enemigos
Revisión de bugs
Mantener la cámara dentro del escenario
El problema al cambiar de escena
Audio
Agregando SFX a nuestro videojuego
Agregando música a nuestro videojuego
Ajustar volúmen del audio de cada uno de los efectos de sonido
Creando un VolumeManager
Agregando economía a nuestro juego y cierre
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Al desarrollar un videojuego, es crucial garantizar que las mecánicas de movimiento sean coherentes y fluidas. Un problema común es cuando un personaje se mueve más rápido en diagonal que en horizontal o vertical, debido a cómo se combinan los vectores de movimiento. Veamos cómo podemos corregir este bug visual siguiendo una metodología sencilla y efectiva.
Cuando combinamos un movimiento horizontal con uno vertical, estamos sumando dos vectores, lo que da lugar a un movimiento diagonal. Según la geometría, esta diagonal es la hipotenusa de un triángulo rectángulo, lo que significa que su longitud es mayor que la de los lados del triángulo (representando los vectores horizontales y verticales). Por lo tanto, en los videojuegos, el personaje puede moverse más rápido de lo esperado. Para corregir esto, es necesario normalizar el vector de movimiento.
Para abordar este problema, debemos modificar nuestro código, asegurándonos de que la velocidad sea uniforme en todas las direcciones. A continuación, se describen los pasos a seguir:
update
del PlayerController
, añadimos una comprobación adicional para ver si el personaje se mueve tanto en horizontal como en vertical.currentSpeed
:currentSpeed
para manejar la velocidad modificada del personaje.Si el personaje se mueve diagonalmente (en dos direcciones), ajustamos currentSpeed
dividiendo la velocidad original por la raíz cuadrada de 2, utilizando mathf.sqrt(2)
.
En caso contrario, currentSpeed
se iguala a la velocidad original.
// Código de ejemplo en C# if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5 && Mathf.Abs(Input.GetAxisRaw("Vertical")) > 0.5) { currentSpeed = speed / Mathf.Sqrt(2); } else { currentSpeed = speed; }
currentSpeed
al movimiento:speed
por currentSpeed
para asegurar que influya adecuadamente en el movimiento del personaje.Además de ajustar la velocidad, debemos tener en cuenta cómo se presentan las animaciones al moverse en diagonal. Diferentes direcciones pueden requerir diferentes animaciones, lo cual es fundamental para mejorar la experiencia del usuario.
Cuando el personaje se mueve en diagonal, es posible que las animaciones requieran priorizar una dirección sobre otra para mantener la consistencia visual.
Podemos crear un sistema que decida por una dirección predominante al mirar en diagonal, facilitando la ejecución de las animaciones adecuadas.
Para el caso de un juego en 2D con movimiento en ocho direcciones, se pueden seguir estos pasos:
Animator
, ajustar las configuraciones para las animaciones de ataque o movimiento.Motion Fields
en las posiciones de coordenadas diagonales como (1,1), (1,-1), (-1,-1), (-1,1).Por cada par de posiciones diagonales, asignar una animación ya existente que se corresponda con una de las direcciones principales (arriba, abajo, izquierda, derecha).
// Ejemplo de pseudocódigo para configurar animaciones if (posicionDiagonal) { animacionAtaque = animacionPrincipalCorrespondiente; }
Con estos ajustes, conseguirás que las animaciones y el control del personaje sean mucho más fluidos y coherentes, lo que contribuye significativamente a una mejor experiencia de juego. Al integrar estas prácticas en tu flujo de trabajo de desarrollo, optimizarás el comportamiento y las animaciones del personaje, manteniéndolos consistentes en cada dirección. ¡Sigue aprendiendo y mejorando tus habilidades de desarrollo de videojuegos!
Aportes 5
Preguntas 0
a pesar que me lo sugiere vsc el if else que agregamos queda mejor con un operador binario:
currentSpeed = Mathf.Abs(Input.GetAxisRaw(horizontal)) && Mathf.Abs(Input.GetAxisRaw(vertical)) ? speed / Mathf.Sqrt(2) : speed
Mucho mejor si en el input tomamos la direccion vertical y horizontal y luego normalizamos el vector y ya, sin necesidad de sacar raiz ni sacar tantos if. Hago todo en 3 updates diferentes, pero pueden escribir todo en uno solo
void Update() {
if (Input.GetMouseButton(0)) {
attacking = true;
walking = false;
attackTimeCounter = attackTime;
direction = Vector2.zero;
}
if (attacking) {
attackTimeCounter -= Time.deltaTime;
if (attackTimeCounter < 0) {
attacking = false;
}
} else {
direction.x = Input.GetAxisRaw(horizontal);
direction.y = Input.GetAxisRaw(vertical);
if (direction != Vector3.zero) {
lastDirection = direction;
walking = true;
} else {
walking = false;
}
}
}
void FixedUpdate() {
rgbd.velocity = speed * direction.normalized;
}
private void LateUpdate() {
anim.SetFloat(horizontal, direction.x);
anim.SetFloat(vertical, direction.y);
anim.SetFloat(lastHorizontal, lastDirection.x);
anim.SetFloat(lastVertical, lastDirection.y);
anim.SetBool(walkingState, walking);
anim.SetBool(attackingState, attacking);
}
Genial
Vamos a optimizar.😎
En mi caso guarde los ejes en variables llamadas x e y para que quede mas corto y use un operador ternario 😃
currentSpeed = Mathf.Abs(x) > .5f && Mathf.Abs(y) > .5f ? speed / Mathf.Sqrt(2) : speed;
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?