Aprende a crear un controlador de jugador en Unity paso a paso: desde configurar el Input Manager hasta programar el movimiento en C# con Input.GetAxisRaw, Mathf.Abs, Time.deltaTime y transform.Translate. Con este enfoque, tendrás un movimiento fluido en horizontal y vertical, listo para iterar en tu roguelike.
¿Cómo preparar el Input Manager para el movimiento en Unity?
Unity ofrece por defecto 18 ejes de entrada para mapear hardware a código. Aquí se usan los ejes Horizontal y Vertical: flechas izquierda/derecha o A/D para horizontal, y flechas arriba/abajo o W/S para vertical. Es clave recordar sus nombres exactos: Horizontal (H mayúscula) y Vertical (V mayúscula).
Usa los ejes predefinidos del Input Manager.
Confirma las teclas: flechas y alternativas WASD.
Verifica mayúsculas en los nombres de ejes.
¿Qué necesita el Player Controller en C# para empezar?
Se crea un script C# llamado PlayerController (sin espacios) y se arrastra al objeto del jugador. Se edita en Visual Studio. La variable public float speed controla la velocidad; al ser pública, puedes ajustarla desde el editor. Un valor inicial recomendado: 4.0f. También se definen constantes para evitar errores de escritura en los nombres de ejes.
El script controla el personaje con flechas o WASD.
La velocidad puede variar: incluso con un power up podría duplicarse.
Constantes: evitan confundir mayúsculas y minúsculas.
Ejemplo de declaración de variables y constantes:
publicclassPlayerController:MonoBehaviour{publicfloat speed =4.0f;// velocidad por defecto.privateconststring horizontal ="Horizontal";privateconststring vertical ="Vertical";voidUpdate(){// Movimiento se implementa aquí.}}
¿Cómo programar el movimiento con Update y Time.deltaTime?
El movimiento usa la ecuación de física espacio = velocidad × tiempo: el desplazamiento depende de speed y de Time.deltaTime (tiempo desde el último frame). Se lee la entrada con Input.GetAxisRaw y se aplica un umbral para evitar ruido del hardware.
¿Por qué usar un umbral con Mathf.Abs > 0.5?
Los dispositivos no son perfectos: pueden generar pequeñas vibraciones. En lugar de comprobar > 0, se usa Mathf.Abs(valor) > 0.5f para iniciar el movimiento solo cuando hay una presión clara de la tecla.
Evita desplazamientos indeseados por ruido.
Acepta entradas parciales sin exigir valor 1.0.
¿Cómo mover en horizontal y vertical con transform.Translate?
Se comprueba cada eje por separado. Si supera el umbral, se traslada el transform en el eje correspondiente. Horizontal mueve en X; vertical mueve en Y; Z se mantiene en 0. Si pulsas dos teclas a la vez, se mueve en diagonal.
voidUpdate(){// Horizontal.float h = Input.GetAxisRaw(horizontal);if(Mathf.Abs(h)>0.5f){ transform.Translate(newVector3(h * speed * Time.deltaTime,0f,0f));}// Vertical.float v = Input.GetAxisRaw(vertical);if(Mathf.Abs(v)>0.5f){ transform.Translate(newVector3(0f, v * speed * Time.deltaTime,0f));}}
Uso de Input.GetAxisRaw: lee la cantidad de pulsación.
Uso de Time.deltaTime: mantiene movimiento suave por frame.
Uso de transform.Translate: aplica el vector de desplazamiento.
Además, verás en el editor la variable speed en el componente del jugador y podrás ajustar la sensación de control. El movimiento inicial es simple: permite salir de pantalla y aún no hay animación, pero sienta una base sólida para pulir el control.
¿Te gustaría mejorar este controlador con desaceleración, límites de pantalla o animaciones? Comenta qué te gustaría implementar a continuación.
Hola Juan disculpa la molestia pero al programar el player controller en visual studio 2017 no me marca el comando mathf, que es lo que puedo hacer????
me pasa lo mismo pero en VS Code, y mi personaje no se mueve
Pueden probar haciendo reload o actualizando Visual Studio.
Resumen de la clase
El objetivo es mover al conejo por el escenario. Vamos a Edit > Project Settings > Input donde vemos los ejes Horizontal y Vertical que serán los controles del movimiento.
Nos creamos el script PlayerController y se lo asignamos al Player. Añadimos las variables Speed, a qué velocidad se moverá, y como buena práctica definimos las constantes horizontal y vertical.
En el Update comprobamos si el valor absoluto del eje Horizontal es superior a un valor, entonces usamos Translate para cambiar la posición del personaje, multiplicando horizontal, speed y el tiempo.
Hacemos lo mismo para el eje vertical. Ahora comprobamos que se mueve el personaje.
Chicos, el movimiento es mejor capturarlo y normalizarlo al momento de crear el vector2. Por que?
Porque la magnitud del vector siempre debe ser = 1.
Ej. Cuando apretamos a la derecha, la magnitud es 1 (x=1 , y=0)
Cuando apretamos arriba la magnitud es 1 (x=0, y=1).
Pero cuando apretamos en diagonal la magnitud se vuelve >1 (x=1, y=1) esto hace que el personaje vaya más rapido al ir en diagonal que al ir hacia los costados o hacia arriba.
Basicamente surge por Pitagoras, c2 = a2 + b2. Si reemplazamos a y b por 1. El resultado da 1,41 dando ese plus de velocidad
Por qué usamos transform.Translate y no rigid.velocity para poder desplazar nuestro personaje?
hola Trixtaro! porque no estamos trabajando directamente con las físicas tradicionales 2D de unity, ya que necesitamos "caminar hacia arriba, abajo y los lados" entonces usamos transform.Traslate para simplemente ir desplazándonos
No entiendo la explicación del profe Ricardo (@ricardocelis). El Translate() traslada al personaje teletransportandolo y no usando las físicas tradicionales tal como dice. Pero para que el personaje tenga colisiones si o si necesita de un Rigidbody2D y para que el mismo no se caiga hay que cambiar la gravity Scale a 0. Por ende tenemos un rigidbody obligatorio e igualmente con el rigidbody.velocity podríamos moverlo hacia arriba y abajo sin ningun problema.
Excelente forma de poder agregar el movimiento al personaje.
Si han visto los anteriores cursos, hemos aprendido distintas maneras de lograr movimiento.
¡Excelente video!
Aqui comparto mi script de movimiento
[SerializeField]public float speed =4.0f;[SerializeField]const string hor ="Horizontal";[SerializeField]const string ver ="Vertical";[SerializeField]Vector2 dir;voidStart(){}voidFixedUpdate(){Movement();}voidMovement(){if(Mathf.Abs(Input.GetAxisRaw(hor))>=.5f){ dir.x=Input.GetAxisRaw(hor)* speed;}if(Mathf.Abs(Input.GetAxisRaw(ver))>=.5f){ dir.y=Input.GetAxisRaw(ver)* speed;} transform.Translate(dir);}
using System.Collections;using System.Collections.Generic;using UnityEngine;publicclassPlayerController:MonoBehaviour{public float speed =4.0f;privateconst string horizontal ="Horizontal";privateconst string vertical ="Vertical";// Start is called before the first frame updatevoidStart(){}// Update is called once per framevoidUpdate(){// s = v*t;//Movimiento horizontalif(Mathf.Abs(Input.GetAxisRaw(horizontal))>0.5f){this.transform.Translate(newVector3(Input.GetAxisRaw(horizontal)*speed*Time.deltaTime,0,0));}//Movimiento verticalif(Mathf.Abs(Input.GetAxisRaw(vertical))>0.5f){this.transform.Translate(newVector3(0,Input.GetAxisRaw(vertical)*speed*Time.deltaTime,0));}}}
Por que usamos Vector3 si no vamos a mover al personaje en el eje Z?
en realidad se usa por que Unity es un motor 3D cuya implementación en 2D sigue existiendo dentro de un mundo 3D
Encantado por esta increíble clase, me gusto el uso de funciones matemáticas como el valor absoluto, siempre es bueno darse su leída sobre matemáticas y física, te pueden ayudar un montón. 😄
Muy útil Math.Abs, para poder darle seguridad al juego :D
//Time.time->Regresa el tiempo transcurrido//Timer.deltaTime->La velocidad a la que corre el juego///Mathf.Abs ->Obtiene el valor numerico sin signo, siendo siempre positivo ```