Menu
CoddyTech

Đẩy vật thể

Thuộc phần Xây dựng trò chơi thực tế trong hành trình Unity của Coddy. Bài học 41 trên 60.

CharacterController không bao giờ đẩy vật thể nào: nếu bạn đi vào một chiếc thùng có Rigidbody, nhân vật sẽ dừng lại như gặp phải bức tường. Thay vào đó, Unity gọi OnControllerColliderHit(ControllerColliderHit hit) trong các script của chính bộ điều khiển cho mọi collider mà một lệnh Move chạm vào, kể cả mặt sàn, và script sẽ quyết định điều gì xảy ra. hit.collider là vật thể bị chạm vào, hit.moveDirection là hướng của lệnh Move đã chạm vào vật thể đó, còn hit.normal là hướng mặt ngoài của vật thể tại điểm tiếp xúc. Đây là script đẩy vật thể do Unity cung cấp:

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // Không có gì để đẩy
    if (hit.moveDirection.y < -0.3f) return;        // Nó nằm dưới chân chúng ta

    Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
    body.linearVelocity = pushDir * pushPower;
}

Mỗi return đều có lý do. Sàn và tường không có Rigidbody, vì vậy body có giá trị null với chúng, và chúng bị chạm vào trong hầu hết mọi lệnh Move. Một vật thể có chuyển động học chỉ di chuyển khi script riêng của nó điều khiển, nên vận tốc không có tác dụng với nó. Khi lệnh Move hướng chếch xuống dưới, nó đã chạm vào vật gì đó dưới chân, và không nên đẩy chiếc thùng mà nhân vật đang đứng lên.

Hướng đẩy chỉ giữ lại x và z, vì vậy chiếc thùng trượt trên mặt đất thay vì bị ép xuống đất. Thiết lập linearVelocity thay vì thêm lực sẽ khiến thùng nhẹ và thùng nặng di chuyển với cùng tốc độ; body.AddForce(pushDir * pushPower, ForceMode.Impulse) sẽ đẩy thùng nặng ít hơn.

challenge icon

Thử thách

Trung bình

Cho người chơi đá những quả bóng mà họ đi vào.

  1. Trong Kicker.cs, viết void OnControllerColliderHit(ControllerColliderHit hit) và lấy Rigidbody body = hit.collider.attachedRigidbody;.
  2. Dùng return khi body là null hoặc ở trạng thái động học, hoặc khi hit.moveDirection.y < -0.3f (bóng nằm dưới chân).
  3. Đặt body.linearVelocity thành hướng đi với y bằng 0, nhân với kickPower, rồi cộng Vector3.up * lift.

Nhấn Chơi rồi đi vào quả bóng đỏ: bóng bay về phía trước và lên cao. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

public class Kicker : MonoBehaviour
{
    public float kickPower = 6f;
    public float lift = 4f;

    // Đá những quả bóng mà người chơi đi vào
}

Tất cả bài học trong Xây dựng trò chơi thực tế

Tự luyện tập: Playground Unity