Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
Movimiento básico
1. Creamos un Plane y lo aplanamos para el suelo.
2. Añadimos un cubo que será nuestro player.
3. Al cubo le añadimos el componente CharacterController.
4. Al cubo le vinculamos el siguiente código que hará que se mueva:
public class PlayerController : MonoBehaviour{
float mX, mZ, mouseX, mouseY, rotationX;
CharacterController characterController;
void Start(){
characterController = GetComponent<CharacterController>();
}
void Update(){
Movement();
}
void Movement(){
mX = Input.GetAxis("Horizontal");
mZ = Input.GetAxis("Vertical");
Vector3 movement = transform.right * mX + transform.forward * mZ;
characterController.Move(movement * Time.deltaTime);
}
}
Definimos una variable para la velocidad del movimiento
characterController.Move(movement * speed* Time.deltaTime);
Rotación en función del ratón
Rotación básica
void Rotation(){
mouseX = Input.GetAxis("Mouse X");
mouseY = Input.GetAxis("Mouse Y");
rotationX -= mouseY;
camera.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.Rotate(Vector2.up * mouseX);
}
Añadimos sensibilidad
mouseX = Input.GetAxis("Mouse X") * sensitivity * Time.deltaTime;
mouseY = Input.GetAxis("Mouse Y") * sensitivity * Time.deltaTime;
Limitamos el rango de movimiento del ratón
rotationX = Mathf.Clamp(rotationX, -90f, 90f);
Hacemos desaparecer el cursor
Este paso será especialmente importante en pasos sucesivos.
Cursor.lockState = CursorLockMode.Locked;
El arma
Añadimos un prisma rectangular que será la pistola y una esfera que será la mira con el objetivo al que estamos apuntando.
Completamos el código del player con el siguiente código:
void Update(){
...
Raycast();
}
void Raycast(){
// Esto tira un rayo desde la cámara
Ray ray = new Ray(playerCamera.position, playerCamera.forward);
Vector3 target;
// Si el rayo colisiona con algo, alimentamos la variable targetHit
if(Physics.Raycast(ray, out RaycastHit targetHit, Mathf.Infinity)){
target = targetHit.point;
}
shotTarget.position = target;
}
Corregir el problema de que el punto de mira no se mueve cuando no colisiona contra nada
else{
target = ray.origin + ray.direction * 1000;
}
Instanciar una bala
Creo un empty en el extremo de la pistola.
void Shot(){
if (Input.GetButtonDown("Fire1")){
GameObject bullet = Instantiate(bulletPrefab, shotOrigin.position, Quaternion.identity);
}
}
Aplicando velocidad a la bala
bullet.transform.LookAt(shotTarget.transform.position);
Bullet.js
public class Bullet : MonoBehaviour{
int speed = 7;
void Update(){
transform.position += transform.forward * speed * Time.deltaTime;
}
}
Destruir la bala cuando colisione
Pondremos la propiedad isTrigger del Box Collider de la bala a true;
private void OnCollisionEnter(Collision collision){
if(collision.gameObject.tag == "World" || collision.gameObject.tag == "Enemy") {
Destroy(gameObject);
}
}
Destruir la bala al cabo de un tiempo (por si la bala no colisionó contra nada)
float timer;
void Update(){
...
timer += Time.deltaTime;
if(timer >= 10){
Destroy(gameObject);
}
}
Salto
Añadimos gravedad
Vector3 fallSpeed;
float gravity = -9.81f;
void Jump()
{
fallSpeed.y += gravity * Time.deltaTime;
characterController.Move(fallSpeed * Time.deltaTime);
}
Evitamos que la gravedad se acumule mientras que el player está en el suelo
bool grounded;
public LayerMask groundMask;
float groundDistanceTest = 0.3f;
void Jump(){
grounded = Physics.CheckSphere(groundTester.position, groundDistanceTest, groundMask);
if (grounded && fallSpeed.y < 0) fallSpeed.y = -2f;
Debemos vincular a una layer llamada Ground, el suelo y los objetos que haya en él.
También debemos indicar el valor de la propiedad ground (de tipo LayerMask en el player).
Saltar
void Jump(){
grounded = Physics.CheckSphere(groundTester.position, groundDistanceTest, groundMask);
if (Input.GetKeyDown(KeyCode.Space) && grounded){
fallSpeed.y = Mathf.Sqrt(5 * -2f * gravity);
}
Gestión de la vida
Añadimos una bala a la escena y le deshabilitamos el código. Reducimos la variable de vida cuando el player colisione contra ella.
private void OnTriggerEnter(Collider other){
if(other.gameObject.tag == "Bullet"){
Destroy(other);
life--;
print(life);
}
}
Vamos a implementar la barra de vida siguiendo las instrucciones del videojuego de plataformas.
Morir
if(health <= 0)
{
print("Morir");
}
Añadir modelo 3D
Sin animación
Para descargar nuestro personaje, iremos a Mixamo. Tener en cuenta que:
- Los personajes rojos son y chicas y los azules, chicos.
De Mixamo debemos descargar:l modelo sin animaciones. Cojeremos los formatos .dae y .fbx. Realmente, el fichero dae no es necesario, pero dentro de su empaquetado vendrá una carpeta con texturas.
En Unity:
1. Seleccionaremos en el panel de proyecto el fichero del modelo → panel inspector → Rig → Animation Type: Humanoid.
Añadimos el modelo a la escena.
Arrastramos los GameObject hijos de Player al Modelo añadido a la escena.
Arrastramos los componentes de Player al Modelo añadido a la escena.
Debemos hacer algunos ajustes para que todo esté correcto:
- Ajustamos el tamaño de la capsula del Character Controller para que se ajuste al tamaño del modelo. Para ello cambiaremos el valor de sus propiedades X, Y, etc..
- Ajustamos la posición de la MainCamera a la posición de la cabeza del personaje.
Animaciones
Vamos a mixamo y descargamos una animación de un personaje andando(walking) y en reposo (idle). En el momento de la descarga, marcaremos la check de inplace. Para las animaciones, descargaremos sólo los ficheros fbx for Unity.
1. Seleccionaremos en el panel de proyecto el fichero del modelo y de la animación → panel inspector → Rig →
- Animation Type: Humanoid.
- Avatar Definition: Copy From Other Avatar → Source: arrastraremos ‘The Boss Avatar’.
3. Seleccionaremos en el panel de proyecto el fichero del modelo y de la animación → panel inspector → Animation → Marcamos las checks de Back Into Pose para Root Transform Rotation, Root Transform Position (Y), Root Transform Position (XZ). Desmarcamos la check de mirror.
3. Creamos una carpeta Animations para las animaciones en 3D.
4. Desplegamos el fichero de Mixamo. Seleccionamos el objeto de la animación. Lo duplicamos (ctrl + d). Arrastramos el duplicado a la carpeta recién creada.
5. Vamos al panel Animator. Botón derecho → Create State → From New Blend Tree
6. En el panel Animator añadimos dos nuevos parámetros de tipo Float: x e y.
7. Hacemos doble click sobre el estado recién creado. Pulsamos sobre el Blend Tree. En el panel inspector:
- Blend Type: 2D Freeform Directional.
- Parameters: x, y
- Añadimos tres campos Motion. Para ello, vamos a la propiedad Motion y le damos a la cruceta → Add Motion Field. Arrastramos las animaciones correspondientes y lo dejamos configurado de la siguiente manera: