Menu
CoddyTech

Engeller

Coddy'nin Unity Oyunu: Gökyüzü Şeritleri kursunda ders 9 / 20.

Şimdi yolda kaçınılması gereken bir şey gerekiyor. Her parçanın ortasına, rastgele bir şeritte bir engel yerleştirilir. Bunu Fill adlı bir metot yapar; Start'ta her yeni parça için ve bir parça tekrar öne geçtiğinde çağrılır.

Oyuncuya biraz zaman tanımak için ilk iki parça boş kalır: Road, made içinde kaç parçayı doldurduğunu sayar.

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) -1, 0 veya 1 değerini verir: tam sayılarda ikinci sayı hiçbir zaman seçilmez.

Yeniden kullanılan bir parçada eski engeli hâlâ bulunur. Clear, etiketi olan her alt nesneyi yok eder. Zemin, çizgiler ve kenarlar Untagged olduğundan yerlerinde kalır:

void Clear(Transform chunk)
{
    foreach (Transform child in chunk)
    {
        if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
    }
}
challenge icon

Görev

Kolay
  1. Road içinde public GameObject barrierPrefab;, public int safeChunks = 2; ve private int made; ekleyin.
  2. Place(chunk, prefab, lane, y, z) yazın: chunk.position + new Vector3(lane * laneWidth, y, z) konumunda, parçanın çocuğu olarak prefab.transform.rotation dönüşüyle prefab'ı oluşturur.
  3. Fill ve Clear işlevlerini yukarıdaki gibi yazın.
  4. Start içinde her parça için Fill(chunk) çağrısı yapın ve bir parça öne geldiğinde Clear(chunk); Fill(chunk); çağrısı yapın.

Kendin dene

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;
    }
}

Unity Oyunu: Gökyüzü Şeritleri bölümündeki tüm dersler

Kendi başına pratik yap: Unity playground