Menu
CoddyTech

Di chuyển con đường

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

Trong trò chơi chạy vô tận, nhân vật đứng yên còn thế giới di chuyển về phía nhân vật. Cũng có thể liên tục di chuyển camera và nhân vật về phía trước, nhưng các con số sẽ tăng mãi không ngừng; di chuyển con đường sẽ giữ mọi thứ gần bằng không.

Tốc độ áp dụng cho toàn bộ trò chơi, nên nó nằm trong GameManager. Road tìm tốc độ một lần trong Start rồi đọc tốc độ đó ở mỗi khung hình:

float step = game.speed * Time.deltaTime;
foreach (Transform chunk in chunks)
{
    chunk.position += Vector3.back * step;
}

Vector3.back là (0, 0, -1): hướng về phía camera. Để di chuyển các mảnh sau này, Road cần ghi nhớ chúng trong một List<Transform>.

challenge icon

Thử thách

Dễ

Di chuyển con đường về phía người chạy.

  1. Trong GameManager, thêm public float startSpeed = 10f; và public float speed;, rồi đặt speed = startSpeed trong Start.
  2. Trong Road, thêm private List<Transform> chunks = new List<Transform>(); (kèm theo using System.Collections.Generic;) và private GameManager game;.
  3. Trong Start, đặt game = FindFirstObjectByType<GameManager>(); và thêm từng phần mới vào chunks.
  4. Viết Update như trên.

Nhấn Chơi: con đường lao về phía người chạy. 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