Presentación del tutorial.
Puedes seguir este tutorial en formato curso en el siguiente enlace: Curso de creación de Runner 2D.
Un juego puede ser una cosa muy complicada, o algo muy sencillo. En este tutorial se ataca un juego sencillo, lo que es mejor se explica de forma sencilla para que en unas pocas horas ya tengas un juego creado por ti mismo en Unity. Mejor que un juego, un pequeño framework, que con pocas modificaciones te va a permitir crear diversos juegos endless runner cambiando tan solo los graficos y usando los scripts que has creado.
El tutorial consta de de cuatro vídeos que no suman ni una hora. Se han dividido en bloques para que sean fáciles de seguir, y puedas hacerlos en varios días.
- Creación y configuración del protagonista.
- Crear la imagen del fondo y hacer el desplazamiento del fondo infinito.
- Configurar los premios y enemigos.
- Ajustes y retoques del juego. Creación de los canvas para el GameOver, el GameManager, contador de puntos y el de vida.
Creación y configuración del protagonista.
En este vídeo veremos como importar las imágenes de nuestro protagonista, crear sus animaciones, y una gran parte del vídeo esta dedicada a la creación del script que maneja a nuestro protagonista.
Empezamos exportando las imágenes necesarias creadas con GIMP, y trabajamos con el sprite, usando el sprite editor de Unity, para poder importar las diferentes imágenes que formaran parte de la animación.
La animación se crea tan solo arrastrando los slide de las imagenes.
Vemos también la creación del script que controlará a nuestro protagonista. El script va a tener un comportamiento parametrizable mediante las variables que nosotros definiremos, donde podremos indicar la velocidad de movimiento, la posición máxima y mínima, un vector de posiciones, o una variable que indica si nuestro personaje pierde o gana vida con el tiempo. Daremos la posibilidad de indicar un Particle System que se ejecute en cada movimiento de nuestro protagonista.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
//Velocidad a la que cambia de carril el caracter
[SerializeField]
private float _speed = 1f;
private Vector2 _targetPos;
private int _maxHeight = 0;
[SerializeField]
private float _iHealth2Update = 0; //Variable que indica la variacion de salud en el tiempo.
[SerializeField]
private float _iHealth = 100, _iPoints = 0;
[SerializeField]
private Vector2[] _positionsAvailable; //Numero de carriles por los que se movera
[SerializeField]
private int _positionActual = 1;
//Sistema de particulas a lanzar al moverse
[SerializeField]
private GameObject particleMove= null;
private bool _isAlive;
// Use this for initialization
private void Awake()
{
//La posicion maxima es la longitud del array de posiciones.
_maxHeight = _positionsAvailable.Length - 1;
}
void Start ()
{
if (_iHealth2Update != 0)
{
/*Invocamos la funcion de modificar la salud, solo si
_iHealth2Update tiene algún valor informado. */
InvokeRepeating("UpdateHealthRep", 1, 1);
}
_isAlive = true; //Informamos de la salud al GameManager para que modifique el canvas.
GameManager.gm.UpdateHealthText(_iHealth);
}
// Update is called once per frame
void Update ()
{
if (_iHealth <= 0){
//En el caso de que la salud sea menor de 0: GameOver!
GameManager.gm.GameOver();
_isAlive = false;
Destroy(gameObject);
}
else{
//Si el player esta vivo movimiento.
transform.position = Vector2.MoveTowards(transform.position, _targetPos, _speed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.UpArrow) && (_positionActual < _maxHeight))
{
//Si se pulsa la tecla arriba, cambiamos la targetPos por una mas grande del array.
if (particleMove != null)
{
Instantiate(particleMove, transform.position, Quaternion.identity);
}
_positionActual += 1;
_targetPos = _positionsAvailable[_positionActual];
}
else if (Input.GetKeyDown(KeyCode.DownArrow) && (_positionActual > 0))
{
//Si se pulsa la tecla abajo, cambiamos la targetPos por una mas pequeña del array.
if (particleMove != null)
{
Instantiate(particleMove, transform.position, Quaternion.identity);
}
_positionActual -= 1;
_targetPos = _positionsAvailable[_positionActual];
}
}
}
public void UpdateHealth(float pHEalth2Update){
if (_isAlive){
_iHealth = _iHealth + pHEalth2Update;
GameManager.gm.UpdateHealthText(_iHealth);
}
}
private void UpdateHealthRep()
{
//Se encarga de ir modificando cada segundo la vida del player.
if (_isAlive)
UpdateHealth(_iHealth2Update);
}
public void UpdatePoints(float pPoints2Update)
{
if (_isAlive){
_iPoints = _iPoints + pPoints2Update;
GameManager.gm.UpdatePointsText(_iPoints);
}
}
}
Al final del post tenéis el enlace para descargaros el proyecto de Unity.
Crear la imagen del fondo y hacer el desplazamiento del fondo infinito.
Vamos a ver los pequeños trucos a aplicar en la creación de una imagen que pueda servir como fondo infinito para nuestro juego. Para crearla uso GIMP, pero los truquillos aplican a cualquier otro software como Photosop o Krita.
Para el movimiento del fondo como no puede ser de otra forma crearemos un script.
Empezamos explicando como usar las capas en GIMP y que necesitamos empezar y acabar la imagen en el mismo punto para que pueda tener continuidad. También se da algún consejo, como evitar puntos de identificación en la imagen que puedan servir al player para identificar un patrón de imagen repetida.
El script que se crea para el movimiento se hace de una forma que pueda ser configurable y reutilizable en diferentes juegos.
<code language=”csharp”>
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ContinousBCK : MonoBehaviour { [SerializeField] private float _speed = 0, _end = 0, _begin = 0, _inverse = 1; // Update is called once per frame void Update () { transform.Translate((Vector2.left * _speed * Time.deltaTime) * _inverse); if (transform.position.x <= _end){ Vector2 startPosition = new Vector2(_begin, transform.position.y); transform.position = startPosition; } } }
Al final del post tenéis el enlace para descargaros el proyecto de Unity.
Premios y enemigos del juego.
¿Que seria de un infinite runner si no tuviéramos nada que recoger y nada que esquivar?
Vemos como crear los spawners (los que lanzan a enemigos y premios y lo que se nos ocurra) y creamos el script de comportamiento de ambos.
Dando los últimos toquecillos a nuestro juego.
El juego ya se puede decir que esta acabado, pero faltan os toques finales, lo que realmente lo convierten en un juego. Crearemos el Gamemanager, responsable de finalizar el juego, o reiniciarlo. Un par de canvas, uno para el Game Over y otro para mostrar la puntuación y la vida del player.
Juego acabado. ¿Ahora que?
Vale, has acabado el juego de ejemplo, tomate tiempo para crear tus propios graficos, de verdad, se pueden conseguir resultados totalmente diferentes tan solo cambiando los gráficos, que lo harán parecer un juego totalmente diferente. Para muestra os dejo este vídeo:
Os aseguro que este juego esta hecho con el mismo framework creado en el tutorial. Quizás algún retoque sin importancia en los scripts. Tan solo han sido modificaciones de los graficos.
Cuando tengáis los gráficos llega el momento de publicar vuestro juego! La verdad es que os recomendaría que por ahora dediquéis tiempo a la versión móvil. Dedicad un par de días a publicarlo en WEB`s de juegos HTML online como kongregate, itch.io, gamejolt o newsground. En algunas de ellas también podéis poner la versión MAC y Windows para que los usuarios se las descarguen. Mi recomendación es que no le pongáis precio. Obtened todo el feedback posible, que la gente lo vea, os siga, y después ya decidís si sacar una versión para Android o iOS.
Para empezar aquí os dejo dos guías que os puede ayudar en la publicación de vuestro primer juego:
Mucha Suerte con vuestros JUEGAZOS!
Podeis descargar el proyecto de Unity usado como ejemplo desde este enlace: Proyecto Infinite Runner Unity.
como hago para que un endless runner tenga un sistemas de misiones?