Hindernisse
Lektion 9 von 20 im Kurs Unity-Spiel: Himmelsbahnen von Coddy.
Jetzt braucht die Straße etwas zum Ausweichen. Jedes Teil bekommt ein Hindernis in der Mitte, auf einer zufällig gewählten Spur. Eine Methode namens Fill erledigt das. Sie wird für jedes neue Teil in Start aufgerufen und erneut jedes Mal, wenn ein Teil wieder nach vorne kommt.
Die ersten beiden Teile bleiben leer, damit der Spieler einen Moment Zeit hat: Road zählt die Teile, die es mit made gefüllt hat.
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) ergibt -1, 0 oder 1: Bei ganzen Zahlen wird die zweite Zahl nie ausgewählt.
Ein wiederverwendetes Teil trägt sein altes Hindernis weiterhin mit sich. Clear zerstört jedes untergeordnete Objekt, das ein Tag hat. Der Boden, die Striche und die Ränder haben das Tag Untagged, also bleiben sie:
void Clear(Transform chunk)
{
foreach (Transform child in chunk)
{
if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
}
}Aufgabe
Einfach- Füge in
Roadpublic GameObject barrierPrefab;,public int safeChunks = 2;undprivate int made;hinzu. - Schreibe
Place(chunk, prefab, lane, y, z): Die Methode erstellt das Prefab an der Positionchunk.position + new Vector3(lane * laneWidth, y, z)mit der Rotationprefab.transform.rotationals untergeordnetes Objekt des Streckenabschnitts. - Schreibe
FillundClearwie oben. - Rufe für jeden Abschnitt in Start
Fill(chunk)auf und rufeClear(chunk); Fill(chunk);auf, wenn ein Abschnitt nach vorne gelangt.
Probier es selbst
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;
}
}
Alle Lektionen in Unity-Spiel: Himmelsbahnen
Übe selbstständig: Unity-Playground