I was going to write this as a comment, but it ended up being rather long winded so I've turned it into an answer.
The current answers are mostly correct, but a few things mentioned are misleading/wrong.
In general, most game-play related tasks will go in Update
.
For example, you don't want to be polling for input in FixedUpdate
(not because of performance, but because the calls simply won't work correctly). AI falls in the same boat.
Continuously updated physics are the only gameplay related task that FixedUpdate
should be used for. Non-continuous/once-in-a-while calls to things like Physics.Raycast
, or even Rigidbody.AddForce
belong in Update
. My mention of Rigidbody.AddForce
is seemingly contrary to what might be implied by the documentation, but the key is Continuous vs Non-continuous.
One huge reason why only continuous physics belong in FixedUpdate
is the actual nature of FixedUpdate
. Other answers have mentioned how FixedUpdate is called at a fixed interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime
/Time.fixedDeltaTime
* which doesn't correspond directly to the actual time between calls, but rather the simulated time between calls.
(*Time.deltaTime
and Time.fixedDeltaTime
are the same value when called in FixedUpdate
[Unity is able to tell if the current call to Time.deltaTime
originated during FixedUpdate
and returns Time.fixedDeltaTime
])
Naturally the same way Update
can't be called in a constant manner because of varying performance, neither can FixedUpdate
. The key difference is, each frame, if FixedUpdate
hasn't been getting called often enough to average out to the correct interval between calls, it gets called multiple times (or isn't called the average is too high). This is what the docs on Execution Order refer to in saying that FixedUpdate can be called multiple times a frame:
... FixedUpdate: FixedUpdate is often called more frequently than Update. It can be called multiple times per frame, if the frame rate is low and it may not be called between frames at all if the frame rate is high...
This doesn't affect Physics because of the nature of the rest of the execution order and the engine, but just about anything else you put in FixedUpdate
will be affected, and it will cause issues.
For example, if you put AI processing inside FixedUpdate
there's no reason to assume that the AI won't skip updates for multiple frames in a row. Additionally, each time `FixedUpdate falls behind, your AI will update multiple times in a single frame before things like physics and player input/movement are processed, which is a waste of processing at the very least, but is also extremely likely to cause hard to track down bugs and erratic behavior.
If you need to do something at a fixed interval use other methods Unity provides such as Coroutines
and InvokeRepeating
.
And a small note on Time.deltaTime
and when to use it:
The easiest way to describe the effect of Time.deltaTime is it changes a number from unit per frame, to unit per second. For example, if you have a script with something like transform.Translate(Vector3.up * 5)
in Update, you're essentially moving the transform at a rate of 5 meters per frame. That means if framerate is low the movement is slower, and if framerate is high, the movement is faster.
If you take that same code and change it to transform.Translate(Vector3.up * 5 * Time.deltaTime)
, the object is being moved at a rate of 5 meters per second. That means no matter the framerate, the object will move 5 meters every second (but the slower the framerate, the jumpier the object's movement will appear since it still moves the same amount every X seconds)
In general, you want your movement to be per second. That way no matter what speed the computer is going at, your physics/movement will behave the same way, and you won't have strange bugs popping up on slower devices.
And there's no point in using it in FixedUpdate
. Because of what I mentioned above, you'll get the same value each call (the Fixed Update Timestep value), and it won't do anything to your values. Movement/Physics defined in FixedUpdate
is already going to be in units per second so you don't need it.