Trong Unity, có nhiều phương pháp để di chuyển nhân vật như sử dụng hàm Transform.translate, áp dụng lực thông qua Rigidbody.AddForce, nội suy bằng Lerp, hệ thống điều hướng, hệ thống hoạt ảnh hoặc các plugin như CharacterController.move và simplemove. Trong đó, phương pháp dùng vật lý (Rigidbody) dựa trên định luật Newton, còn Translate và Lerp thay đổi trực tiếp vị trí, quay, tỷ lệ để tạo hiệu ứng di chuyển. Các plugin khác sẽ có cơ chế riêng, ở đây không đề cập chi tiết.
Dưới đây trình bày một số cách đơn giản, những phương pháp còn lại sẽ được bổ sung sau.
I. Lấy đầu vào từ chuột/phím bấm
Các phương pháp phổ biến:
- Sử dụng
Input.GetKey,Input.GetKeyDown,Input.GetKeyUpđể xác định trạng thái phím. Ví dụ kiểm tra phím A được nhấn:
Input.GetKeyDown(KeyCode.A);
- Truy cập Axes trong InputManager để lấy các trục ngang (Horizontal), dọc (Vertical) và thông tin chuột. Cách sử dụng:
float chiHuongNgang = Input.GetAxisRaw("Horizontal");
float chiHuongDoc = Input.GetAxisRaw("Vertical");
Lưu ý tên chuỗi trong GetAxisRaw phải chính xác và phân biệt chữ hoa/thường. Hàm GetAxisRaw không làm mượt đầu vào, phù hợp cho di chuyển chính xác.
II. Phương pháp Translate
float chiHuongNgang = Input.GetAxisRaw("Horizontal");
float chiHuongDoc = Input.GetAxisRaw("Vertical");
if (chiHuongDoc > 0)
{
this.gameObject.transform.Translate(ToCDo * Time.deltaTime * Vector3.forward);
}
if (chiHuongDoc < 0)
{
this.gameObject.transform.Translate(ToCDo * Time.deltaTime * -Vector3.forward);
}
if (chiHuongNgang > 0)
{
this.gameObject.transform.Translate(ToCDo * Time.deltaTime * Vector3.right);
}
if (chiHuongNgang < 0)
{
this.gameObject.transform.Translate(ToCDo * Time.deltaTime * Vector3.left);
}
Giải thích: GetAxisRaw trả về giá trị [-1,1]. Khi giá trị dương, vật thể di chuyển theo hướng tương ứng (ví dụ: Vector3.right cho hướng phải). Tham số hàm Translate là vận tốc nhân thời gian và hướng di chuyển.
III. Vật lý (Physics Engine)
- Thiết lập vận tốc trực tiếp:
Vector3 chuyenDong = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
rigidbody.velocity = new Vector3(chuyenDong.x * tocDo, rigidbody.velocity.y, chuyenDong.z * tocDo);
- Áp dụng lực:
rigidbody.AddForce(new Vector3(lucX, 0f, lucZ), ForceMode.Impulse);
Lưu ý: ForceMode.Impulse tạo lực tức thời. Chi tiết về vật lý sẽ được trình bày trong phần chuyên sâu.
IV. Nội suy (Lerp)
Vấn đề với Lerp:
Vector3.Lerp(this.transform.position, viTriMucTieu, Time.deltaTime);
Hiệu ứng nội suy khiến vật thể tiến gần dần đến đích nhưng không đạt chính xác. Có hai cách khắc phục: sử dụng đường cong hoặc thay đổi hệ số nội suy liên tục. Giải pháp cụ thể sẽ được cập nhật khi bàn về hệ thống điều hướng và hoạt ảnh.
V. CharacterController
Cảnh báo: Tránh kết hợp CharacterController với vật lý vì gây xung đột trong di chuyển.