FixedUpdate cho vật lý
Thuộc phần Vật lý và lối chơi trong hành trình Unity của Coddy. Bài học 4 trên 71.
Unity di chuyển các vật thể theo từng bước vật lý cố định, mỗi bước dài 0.02 giây (Time.fixedDeltaTime), tức 50 lần mỗi giây, bất kể tốc độ khung hình. FixedUpdate() chạy ngay trước mỗi bước. Update() chạy một lần mỗi khung hình được vẽ, có thể là 30, 60 hoặc 144 lần mỗi giây: ở tốc độ 144, hầu hết các khung hình không có bước vật lý nào, còn trên máy tính chậm, một khung hình có thể chứa hai bước.
Từ đó có hai quy tắc. Lực được thêm trong Update() sẽ được thêm một lần mỗi khung hình, nên máy tính nhanh hơn sẽ đẩy mạnh hơn: hãy thêm các lực tác động theo thời gian trong FixedUpdate(). Còn GetKeyDown chỉ trả về true trong một khung hình; nếu khung hình đó không có bước vật lý, FixedUpdate() sẽ không nhận được thao tác nhấn và thao tác đó bị bỏ lỡ. Vì vậy, hãy đọc thao tác nhấn trong Update(), lưu lại trong một bool, rồi xử lý trong FixedUpdate(). Con thuyền này được gió đẩy đều và lướt nhanh sang bên khi nhấp chuột:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // ghi nhớ lần nhấp chuột
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // đẩy đều ở mỗi bước
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // mỗi lần nhấp chuột, một lần lướt
}
}Việc đặt lại bool sau khi dùng rất quan trọng: nếu để nguyên true, thuyền sẽ lướt nhanh ở mỗi bước. Bạn cũng có thể thêm một xung lực ngay trong Update(), như cú nhảy của chú ếch; dùng bool giúp gom mọi lực vào một chỗ, cạnh những lực mà nó phối hợp. Các phím được giữ (GetKey, GetAxis) biểu thị một trạng thái chứ không phải một thời điểm, nên FixedUpdate() có thể đọc chúng trực tiếp. Bên trong FixedUpdate(), Time.deltaTime trả về thời lượng của bước, là 0.02.
Thử thách
DễĐặt hai nhiệm vụ của xe trượt tuyết vào đúng phương thức.
- Chuyển hai khối
ifđiều khiển mũi tên từUpdate()sangFixedUpdate(). - Thêm
private bool hopPressed;. TrongUpdate(), đặt biến này thànhtruekhi cóInput.GetKeyDown(KeyCode.Space). - Trong
FixedUpdate(), khihopPressedđược đặt, hãy thêm lực đẩy tức thời, rồi đặt biến này thànhfalse.
Nhấn Chơi: các phím mũi tên đẩy xe đều đặn và mỗi lần nhấn Space, xe sẽ nhảy. Sau đó nhấn Kiểm tra.
Tự làm thử
using UnityEngine;
public class Sled : MonoBehaviour
{
public float push = 6f;
public float hop = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(Vector3.right * push);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(Vector3.left * push);
}
}
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * hop, ForceMode.Impulse);
}
}
}
Tất cả bài học trong Vật lý và lối chơi
1Rigidbody
Trọng lực và khối lượngĐẩy bằng AddForceNhảy bằng xung lựcFixedUpdate cho vật lýVận tốcVật thể động họcÔn tập: Bệ phóng4Coroutine
InvokeInvokeRepeating, CancelInvokeCoroutine đầu tiên của bạnVòng lặp trong CoroutineDừng CoroutineÔn tập: đếm ngược10Dự án: Thoát khỏi đấu trường
Đấu trườngThợ săn2Va chạm
OnCollisionEnterMình đã va chạm với gì?Vỡ khi va chạmĐứng trên mặt đấtĐộ nảy và ma sátHình dạng colliderÔn tập: Tường có thể phá vỡ5Dự án: Cuộc đua thu thập xu
Quả bóng lănThu thập xuTự luyện tập: Playground Unity