Chciałem napisać to jako komentarz, ale skończyło się to dość długim rozwiązywaniem, więc przekształciłem to w odpowiedź.
Obecne odpowiedzi są w większości poprawne, ale kilka wspomnianych rzeczy jest mylących / błędnych.
Ogólnie rzecz biorąc, większość zadań związanych z grą zostanie wykonana Update
.
Na przykład nie chcesz odpytywać danych wejściowych FixedUpdate
(nie ze względu na wydajność, ale ponieważ wywołania po prostu nie będą działać poprawnie). AI wpada do tej samej łodzi.
Ciągle aktualizowana fizyka to jedyne zadanie związane z rozgrywką, do którego FixedUpdate
należy się zastosować. Nieciągłe / raz na jakiś czas połączenia do takich rzeczy Physics.Raycast
, a nawet do nich Rigidbody.AddForce
należą Update
. Moja wzmianka o Rigidbody.AddForce
pozornie jest sprzeczna z tym, co może wynikać z dokumentacji, ale kluczem jest ciągły kontra nieciągły.
Jednym z ogromnych powodów, dla których należą tylko ciągła fizyka, FixedUpdate
jest faktyczna natura FixedUpdate
. W innych odpowiedziach wspomniano, w jaki sposób FixedUpdate jest wywoływany jako fixed interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime
/ Time.fixedDeltaTime
*, który nie odpowiada bezpośrednio faktycznemu czasowi między rozmowami, ale raczej symulowanemu czasowi między rozmowami.
(* Time.deltaTime
i Time.fixedDeltaTime
mają tę samą wartość, gdy są wywoływane w FixedUpdate
[Unity jest w stanie stwierdzić, czy bieżące wywołanie zostało nawiązane Time.deltaTime
podczas FixedUpdate
i zwraca Time.fixedDeltaTime
])
Oczywiście tego samego sposobu Update
nie można wywoływać w sposób ciągły ze względu na różną wydajność, nie można tego zrobić FixedUpdate
. Kluczową różnicą jest to, że każda ramka, jeśli FixedUpdate
nie była wywoływana wystarczająco często, aby uśrednić prawidłowy odstęp między połączeniami, jest wywoływana wiele razy (lub nie jest nazywana średnia jest zbyt wysoka). Oto do czego odnoszą się dokumenty dotyczące polecenia wykonania, mówiąc, że FixedUpdate można wywoływać wiele razy ramkę:
... FixedUpdate: FixedUpdate jest często nazywany częściej niż Aktualizacja. Może być wywoływany wiele razy na klatkę, jeśli częstotliwość klatek jest niska i może nie być w ogóle wywoływana między klatkami, jeśli częstotliwość klatek jest wysoka ...
Nie wpływa to na fizykę ze względu na naturę pozostałej kolejności wykonania i silnika, ale FixedUpdate
wpłynie to na wszystko, co włożysz , i spowoduje problemy.
Na przykład, jeśli umieścisz w nim przetwarzanie AI, FixedUpdate
nie ma powodu, aby zakładać, że AI nie pominie aktualizacji wielu ramek z rzędu. Dodatkowo, za każdym razem, gdy `FixedUpdate pozostaje w tyle, twoja sztuczna inteligencja aktualizuje się wiele razy w jednej klatce, zanim zostaną przetworzone takie rzeczy jak fizyka i wejście / ruch gracza, co jest co najmniej marnotrawstwem przetwarzania, ale jest również bardzo prawdopodobne, że spowoduje trudne aby wyśledzić błędy i nieprawidłowe zachowanie.
Jeśli chcesz coś zrobić w ustalonym odstępie czasu, użyj innych metod, które zapewnia Unity, takich jak Coroutines
i InvokeRepeating
.
I mała uwaga na temat Time.deltaTime
i kiedy go używać:
Najłatwiejszym sposobem opisania efektu Time.deltaTime jest zmiana liczby z jednostki na ramkę na jednostkę na sekundę . Na przykład, jeśli masz skrypt z czymś takim jak transform.Translate(Vector3.up * 5)
w aktualizacji, zasadniczo przesuwasz transformację z prędkością 5 metrów na klatkę . Oznacza to, że jeśli liczba klatek na sekundę jest niska, ruch jest wolniejszy, a jeśli liczba klatek na sekundę jest wysoka, ruch jest szybszy.
Jeśli weźmiesz ten sam kod i zmienisz na transform.Translate(Vector3.up * 5 * Time.deltaTime)
, obiekt będzie przemieszczany z prędkością 5 metrów na sekundę . Oznacza to, że bez względu na liczbę klatek na sekundę obiekt porusza się o 5 metrów co sekundę (ale im wolniejsza liczba klatek na sekundę, tym bardziej ruch obiektu będzie się pojawiał, ponieważ nadal porusza się o tę samą wartość co X sekund)
Ogólnie rzecz biorąc, chcesz, aby twój ruch był na sekundę. W ten sposób, bez względu na prędkość komputera, fizyka / ruch będą się zachowywać w ten sam sposób i nie będziesz mieć dziwnych błędów pojawiających się na wolniejszych urządzeniach.
I nie ma sensu z niego korzystać FixedUpdate
. Z powodu tego, o czym wspomniałem powyżej, będziesz otrzymywać tę samą wartość dla każdego połączenia (wartość ustalonego timepeptu aktualizacji) i nie wpłynie to na twoje wartości. Zdefiniowany ruch / fizyka FixedUpdate
będzie już w jednostkach na sekundę, więc go nie potrzebujesz.