Menu
CoddyTech

Trượt

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

Một số chướng ngại vật treo quá cao để nhảy qua, nên nhân vật chạy phải trượt bên dưới. Khi trượt, nhân vật chạy tạm thời chỉ cao bằng một nửa.

Thu nhỏ đối tượng cũng làm thu nhỏ CharacterController của nó, nhưng đối tượng thu nhỏ quanh điểm giữa, nên chân sẽ lơ lửng cao hơn mặt đường nửa đơn vị. Hạ nhân vật chạy xuống đúng nửa đơn vị đó. Phải tắt bộ điều khiển khi bạn di chuyển nó bằng tay, nếu không lần gọi Move tiếp theo sẽ hoàn tác thay đổi:

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

Một bộ đếm thời gian, slide, đếm ngược thời gian trượt. Khi hết giờ, nhân vật chạy đứng thẳng trở lại bằng StopSlide:

void StopSlide()
{
    if (transform.localScale.y < 1f) Resize(1f);
    slide = 0f;
}
challenge icon

Thử thách

Dễ

Cho nhân vật chạy trượt bên dưới các vật thể.

  1. Thêm public float slideTime = 0.7f;, private float slide;, cùng với Resize và StopSlide như trên.
  2. Khi nhấn S hoặc phím mũi tên xuống lúc nhân vật đang ở trên mặt đất, đặt slide = slideTime và gọi Resize(0.5f).
  3. Mỗi khung hình khi slide > 0f, trừ Time.deltaTime khỏi giá trị này; khi giá trị về 0, gọi StopSlide().
  4. Cú nhảy kết thúc động tác trượt: gọi StopSlide() khi nhân vật nhảy.

Nhấn Chơi rồi nhấn S: nhân vật cúi xuống trong giây lát, sau đó đứng thẳng. Tiếp theo, 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 int lane;

    private CharacterController controller;
    private float fallSpeed;

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

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

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