Como crear un infinite runner 2D con UNITY
Creando los enemigos y los premios de nuestro Runner
Lo principal va a ser la creación de los spawner. ¿Que es un spawner? Pues son los responsables de lanzar, o de instanciar, los enemigos o los diferentes objetos de nuestro juego. Un spawner en Unity suele ser un objeto vacío que contiene un script, y es este script el responsable de ir lanzando los objetos que le indiquemos.
Cualquier duda o comentario de la lección no dudeis en dejarla en el foro del curso.
El script de los spawners:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spawner : MonoBehaviour { //Array que contiene los items a lanzar public GameObject[] floatingItemsPatterns; /* * _timeBetweenItems: El tiempo que transcurre entre que se lanza un item y el siguiente lanzamiento. * _increaseSpawn: Si es positivo reduce el tiempo de espera a cada lanzamiento. Si es negativo lo aumenta. * _minSpawnTime: Por mucho que se reduzca el tiempo de lanzamiento nunca podra ser menor a este valor. * */ [SerializeField] private float _timeBetweenItems = 10, _increaseSpawn = 0, _minSpawTime = 0.65f; [SerializeField] //Si esta informado indica el numero maximo de items a lanzar. private float _maxNumItems = 0f; /*Algunas de estas variables estan por motivos de claridad del código, * pero podria obtenerse la misma utilidad sin ellas. * */ //Contendra el numero rando que indica que objeto del array a lanzar private int _rnd = 0; //Longitud del array. private int _lengthFP; //Tiempo de espera entre lanzamientos despues del calculo. private float _timeWaitNew = 1; //Contador de items lanzados. private float _itemsSpawned = 0; void Start () { //Al inicio esperamnos el tiempo indicado en la variable publica _timeBetweenItems _timeWaitNew = _timeBetweenItems; //Se obtiene la longitud del array. _lengthFP = floatingItemsPatterns.Length; } void Update () { if (_timeWaitNew <= 0 && (_maxNumItems == 0 || _maxNumItems > _itemsSpawned)) { /* * Este codigo se ejecuta en caso de que _timeWaitNew sea menor o igual a 0, * y que _maxnumItems tenga el valor 0 o sea menor que el numero * de items lanzados * */ //Obtenemos un numero, como maximo la longitud del array,indica el objeto a lanzar. _rnd = Random.Range(0, _lengthFP); //Instanciamos el objeto, en la posición del spawner. Instantiate(floatingItemsPatterns[_rnd], transform.position, Quaternion.identity); //Si valor en _increaseSpawn lo restamos de _timeBetweenItems. if (_increaseSpawn >= 0) _timeBetweenItems -= _increaseSpawn; //El nuevo tiempo de espera entre items. _timeWaitNew = _timeBetweenItems; //Si el nuevo tiempo es menor que el mínimo lo igualamos al mínimo. if (_timeWaitNew < _minSpawTime) _timeWaitNew = _minSpawTime; //Incrementamos el contador de objetos lanzados. _itemsSpawned += 1; } else { //Restamos el tiempo transcurrido de _timeWaitNew. _timeWaitNew -= Time.deltaTime; } } }
El siguiente script a crear es el que van a llevar los objetos voladores. Este script serà el responsable de moverlos y permitirá configurar la velocidad de movimiento, e incluso una variación aleatoria de la velocidad para que no todos los objetos se muevan igual de rápido.
También se le podrá indicar los puntos que obtiene el jugador al recogerlo, o los puntos de vida que le resta al chocar con él. Tengamos en cuenta que si informamos un valor negativo en puntos o en la vida en lugar de aumentar los reducirá.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FloatingItemScript : MonoBehaviour { [SerializeField] private int _points = -1, _health = -1; [SerializeField] private float _speed = 2f, _varSpeed = 0f; [SerializeField] private GameObject _explosion = null; void Start () { /* * En el caso de que tengamos informado el _varSpeed * calcularemos una velocidad diferente para * cada objeto lanzado. * */ if (_varSpeed > 0.0f) { float originalSpeed = _speed; /* * Obtenemos una velocidad mínima y una maxima restando y sumando * la velocidad que queremos variar. * */ float minimal = originalSpeed - _varSpeed; float max = originalSpeed + _varSpeed; //Aqui tenemos la nueva velocidad del objeto _speed = Random.Range(minimal, max); } } void Update () { transform.Translate(Vector2.left * _speed * Time.deltaTime); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.CompareTag("Player")) { /*En caso de que choquemos con el Player. * Serà el player el responsable de lo que hacer con los valores * que le pasamos, en este script nos limitamos a llamar * a sus variables publicas. * */ if (_health != 0) collision.GetComponent<PlayerController>().UpdateHealth(_health); if (_points != 0) collision.GetComponent<PlayerController>().UpdatePoints(_points); if (_explosion != null) Instantiate(_explosion, transform.position, Quaternion.identity); Destroy(gameObject); } } }
Creamos otro script muy sencillo, que se llama CleanMemory y que lo único que hace es destruir el objeto pasados los segundos que le indiquemos.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CleanMemory : MonoBehaviour { [SerializeField] private float destroyAfter = 2.0f; void Start () { Destroy(gameObject, destroyAfter); } }
Extras:
Hemos creado un spawner muy sencillo. En este vídeo podéis ver la creación de un spawner mucho más profesional y con muchas más opciones.