Obstáculos
Lección 9 de 20 del curso Juego de Unity: Carriles celestes de Coddy.
Ahora la carretera necesita algo que esquivar. Cada pieza recibe un obstáculo en el medio, en un carril aleatorio. Un método se encarga de ello: Fill, que se llama para cada pieza nueva en Start y, de nuevo, cada vez que una pieza vuelve al frente.
Las dos primeras piezas se quedan vacías para darle un momento al jugador: Road cuenta las piezas que ha rellenado en made.
void Fill(Transform chunk)
{
made++;
if (made <= safeChunks) return;
int lane = Random.Range(-1, 2);
Place(chunk, barrierPrefab, lane, 0.5f, 0f);
}Random.Range(-1, 2) devuelve -1, 0 o 1: con números enteros, nunca se elige el segundo número.
Una pieza reciclada aún conserva su antiguo obstáculo. Clear destruye todos los elementos secundarios que tengan una etiqueta. El suelo, las líneas discontinuas y los bordes no tienen etiqueta, así que se quedan:
void Clear(Transform chunk)
{
foreach (Transform child in chunk)
{
if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
}
}Desafío
Fácil- En
Road, añadepublic GameObject barrierPrefab;,public int safeChunks = 2;yprivate int made;. - Escribe
Place(chunk, prefab, lane, y, z): crea el prefab enchunk.position + new Vector3(lane * laneWidth, y, z)conprefab.transform.rotation, como hijo de la pieza. - Escribe
FillyClearcomo arriba. - Llama a
Fill(chunk)para cada pieza en Start, y aClear(chunk); Fill(chunk);cuando una pieza pase al frente.
Pruébalo tú mismo
using UnityEngine;
public class Runner : MonoBehaviour
{
public float laneWidth = 2.5f;
public float laneSpeed = 16f;
public float jumpHeight = 1.6f;
public float gravity = -40f;
public float slideTime = 0.7f;
public int lane;
private CharacterController controller;
private float fallSpeed;
private float slide;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);
bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
if (jump && controller.isGrounded)
{
fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
StopSlide();
}
if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && controller.isGrounded)
{
slide = slideTime;
Resize(0.5f);
}
if (slide > 0f)
{
slide -= Time.deltaTime;
if (slide <= 0f) StopSlide();
}
if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
fallSpeed += gravity * Time.deltaTime;
float targetX = lane * laneWidth;
float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
Vector3 move = new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f);
controller.Move(move);
}
void StopSlide()
{
if (transform.localScale.y < 1f) Resize(1f);
slide = 0f;
}
void Resize(float height)
{
controller.enabled = false;
transform.position += Vector3.up * (height - transform.localScale.y);
transform.localScale = new Vector3(1f, height, 1f);
controller.enabled = true;
}
}
Todas las lecciones de Juego de Unity: Carriles celestes
Practica por tu cuenta: Playground de Unity