Menu
CoddyTech

Va chạm

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

Chướng ngại vật là các bộ kích hoạt: chúng phát hiện người chạy mà không đẩy người đó. Khi CharacterController của người chạy chạm vào một bộ kích hoạt, Unity gọi OnTriggerEnter trong các tập lệnh của người chạy, kèm theo collider của bộ kích hoạt:

void OnTriggerEnter(Collider other)
{
    if (game.over) return;
    if (other.CompareTag("Obstacle"))
    {
        game.GameOver();
    }
}

GameOver kết thúc lượt chạy: over chuyển thành true, tốc độ về 0 nên con đường dừng lại, và thông báo ở giữa màn hình cho biết điều đó. Khi over là true, GameManager ngừng tính quãng đường và Runner ngừng đọc các phím.

challenge icon

Thử thách

Trung bình

Kết thúc lượt chạy khi nhân vật chạy đâm vào rào chắn.

  1. Trong GameManager, thêm public TMP_Text messageText; và public bool over;, rồi bắt đầu Update bằng if (over) return;.
  2. Thêm public void GameOver(): trả về nếu over; nếu không, đặt over = true, speed = 0f và messageText.text = "Game over".
  3. Trong Runner, tìm GameManager trong Start, chỉ đọc các phím khi !game.over và thêm OnTriggerEnter như trên.

Nhấn Chơi và chạy đâm vào rào chắn: con đường sẽ dừng lại và dòng Game over sẽ hiện ra. 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