Menu
CoddyTech

Chướng ngại vật

Bài học 9 trên 21 trong khóa học Trò chơi Unity: đường đua trên trời của Coddy.

Giờ con đường cần có thứ gì đó để né tránh. Mỗi đoạn đường có một chướng ngại vật ở giữa, nằm trên một làn đường ngẫu nhiên. Phương thức Fill thực hiện việc này, được gọi cho mỗi đoạn đường mới trong Start và mỗi lần một đoạn đường quay lại phía trước.

Hai đoạn đường đầu tiên vẫn để trống để người chơi có thời gian làm quen: Road đếm số đoạn đường đã thêm chướng ngại vật trong 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) trả về -1, 0 hoặc 1: với số nguyên, số thứ hai không bao giờ được chọn.

Một đoạn đường được tái sử dụng vẫn còn chướng ngại vật cũ. Clear hủy mọi đối tượng con có tag. Sàn, vạch đứt và mép đường không có tag, nên chúng vẫn được giữ lại:

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

Thử thách

Dễ

Đặt một chướng ngại vật trên mỗi đoạn đường.

  1. Trong Road, thêm public GameObject barrierPrefab;, public int safeChunks = 2; và private int made;.
  2. Viết Place(chunk, prefab, lane, y, z): đặt prefab tại chunk.position + new Vector3(lane * laneWidth, y, z), dùng prefab.transform.rotation và đặt làm đối tượng con của đoạn đường.
  3. Viết Fill và Clear như trên.
  4. Gọi Fill(chunk) cho mỗi đoạn đường trong Start, và gọi Clear(chunk); Fill(chunk); khi một đoạn đường chuyển lên đầu.

Nhấn Chơi: một chướng ngại vật màu đỏ xuất hiện ở một làn đường ngẫu nhiên trên mỗi đoạn đường sau hai đoạn đầu tiên. Sau đó nhấn Kiểm tra.

Tự làm thử

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

Tất cả bài học trong Trò chơi Unity: đường đua trên trời

Tự luyện tập: Playground Unity