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.
Thử thách
Trung bìnhKết thúc lượt chạy khi nhân vật chạy đâm vào rào chắn.
- Trong
GameManager, thêmpublic TMP_Text messageText;vàpublic bool over;, rồi bắt đầu Update bằngif (over) return;. - Thêm
public void GameOver(): trả về nếuover; nếu không, đặtover = true,speed = 0fvàmessageText.text = "Game over". - Trong
Runner, tìm GameManager trong Start, chỉ đọc các phím khi!game.overvà thêmOnTriggerEnternhư 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