Tôi sẽ viết nó như một bình luận, nhưng cuối cùng nó khá dài nên tôi đã biến nó thành một câu trả lời.
Các câu trả lời hiện tại hầu hết đều đúng, nhưng một vài điều được đề cập là sai / sai.
Nói chung, hầu hết các nhiệm vụ liên quan đến chơi trò chơi sẽ đi vào Update
.
Ví dụ: bạn không muốn bỏ phiếu cho đầu vào FixedUpdate
(không phải vì hiệu suất, mà vì các cuộc gọi đơn giản là không hoạt động chính xác). AI rơi vào cùng một chiếc thuyền.
Vật lý được cập nhật liên tục là nhiệm vụ duy nhất liên quan đến trò chơi FixedUpdate
nên được sử dụng cho. Các cuộc gọi không liên tục / một lần trong một thời gian đến những thứ như Physics.Raycast
, hoặc thậm chí Rigidbody.AddForce
thuộc về Update
. Đề cập của tôi Rigidbody.AddForce
dường như trái ngược với những gì có thể được ngụ ý trong tài liệu, nhưng chìa khóa là Liên tục so với Không liên tục.
Một lý do lớn tại sao chỉ có vật lý liên tục thuộc về FixedUpdate
bản chất thực tế của FixedUpdate
. Các câu trả lời khác đã đề cập đến cách FixedUpdate được gọi ở mức cố định interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime
/ Time.fixedDeltaTime
* không tương ứng trực tiếp với thời gian thực tế giữa các cuộc gọi, mà là thời gian mô phỏng giữa các cuộc gọi.
(* Time.deltaTime
và Time.fixedDeltaTime
là cùng một giá trị khi được gọi trong FixedUpdate
[Unity có thể cho biết nếu cuộc gọi hiện tại được Time.deltaTime
khởi tạo trong FixedUpdate
và trả về Time.fixedDeltaTime
])
Đương nhiên, cùng một cách Update
không thể được gọi một cách liên tục vì hiệu suất khác nhau, cũng không thể FixedUpdate
. Sự khác biệt chính là, mỗi khung hình, nếu FixedUpdate
không được gọi thường xuyên đủ để tính trung bình cho khoảng thời gian chính xác giữa các cuộc gọi, nó sẽ được gọi nhiều lần (hoặc không được gọi là mức trung bình quá cao). Đây là những gì các tài liệu trên Lệnh thực thi đề cập đến khi nói rằng FixedUpdate có thể được gọi nhiều lần trong một khung:
... FixedUpdate: FixedUpdate thường được gọi thường xuyên hơn Cập nhật. Nó có thể được gọi nhiều lần trên mỗi khung hình, nếu tốc độ khung hình thấp và có thể không được gọi giữa các khung hình nếu tốc độ khung hình cao ...
Điều này không ảnh hưởng đến Vật lý vì bản chất của phần còn lại của lệnh thực hiện và động cơ, nhưng bất kỳ thứ gì khác bạn đặt vào FixedUpdate
sẽ bị ảnh hưởng và nó sẽ gây ra sự cố.
Ví dụ: nếu bạn đặt xử lý AI bên trong FixedUpdate
thì không có lý do gì để cho rằng AI sẽ không bỏ qua các bản cập nhật cho nhiều khung hình liên tiếp. Ngoài ra, mỗi lần `FixedUpdate tụt lại phía sau, AI của bạn sẽ cập nhật nhiều lần trong một khung hình trước khi những thứ như vật lý và đầu vào / chuyển động của người chơi được xử lý, điều này rất lãng phí khi xử lý, nhưng cũng cực kỳ gây ra khó khăn để theo dõi lỗi và hành vi thất thường.
Nếu bạn cần làm gì đó trong một khoảng thời gian cố định, hãy sử dụng các phương pháp khác mà Unity cung cấp như Coroutines
và InvokeRepeating
.
Và một lưu ý nhỏ về Time.deltaTime
và khi nào nên sử dụng nó:
Cách dễ nhất để mô tả hiệu ứng của Time.deltaTime là thay đổi một số từ đơn vị trên mỗi khung, thành đơn vị mỗi giây . Ví dụ: nếu bạn có một tập lệnh giống như transform.Translate(Vector3.up * 5)
trong Cập nhật, về cơ bản, bạn đang di chuyển biến đổi với tốc độ 5 mét mỗi khung hình . Điều đó có nghĩa là nếu tốc độ khung hình thấp thì chuyển động chậm hơn và nếu tốc độ khung hình cao thì chuyển động nhanh hơn.
Nếu bạn lấy cùng mã đó và đổi nó thành transform.Translate(Vector3.up * 5 * Time.deltaTime)
, đối tượng đang được di chuyển với tốc độ 5 mét mỗi giây . Điều đó có nghĩa là bất kể tốc độ khung hình, vật thể sẽ di chuyển 5 mét mỗi giây (nhưng tốc độ khung hình càng chậm, chuyển động của vật thể sẽ càng xuất hiện vì nó vẫn di chuyển cùng một lượng mỗi X giây)
Nói chung, bạn muốn chuyển động của bạn được mỗi giây. Theo cách đó, bất kể máy tính đang hoạt động ở tốc độ nào, vật lý / chuyển động của bạn sẽ hoạt động theo cùng một cách và bạn sẽ không gặp phải những lỗi lạ xuất hiện trên các thiết bị chậm hơn.
Và không có điểm nào trong việc sử dụng nó trong FixedUpdate
. Vì những gì tôi đã đề cập ở trên, bạn sẽ nhận được cùng một giá trị cho mỗi cuộc gọi (giá trị Dấu thời gian cập nhật cố định) và nó sẽ không làm gì với giá trị của bạn. Chuyển động / Vật lý được xác định trong FixedUpdate
sẽ có đơn vị mỗi giây vì vậy bạn không cần nó.