I made an more in depth explanation on GitHub: link.
Graphics or Physics
One difference is that _process
is tied to graphics (it runs once per frame), while _physics_process
isn't. As such, VSync (which is on by default) will affect _process
, depending on the monitor frame rate, of course. Use it for anything graphics related.
The other is that _physics_process
is tied to the physics, while _process
isn't. As such, Physics FPS (which is 60 by default) will be the target frame rate for _physics_process
. Godot will call _physics_process
before computing physics response, and thus to get that correct physics response, use _physics_process
for anything physics related.
If your script need to read any properties that the physics server will update (e.g position, ray casts), then avoid reading them in _process
. See Physics process callback.
Is moving a node graphics or physics? If it is a PhysicsBody
or PhysicsBody2D
consider it physics (corollary: use _physics_process
to move KinematicBody
and its 2D counterpart). Otherwise, it is graphics.
What if you need to compute something with a stable frequency, but it does not affect physics, nor graphics? Well, it is neither. While it is often harmless to hijack either _process
or _physics_process
, consider using a Timer
(or a coroutine, or a Thread
with a good old loop).
By the way, you can disable using set_process
and set_physics_process
.
Input
For input, I would make the same distinction as for anything else. Should the input update graphics (e.g. it is a Control
)? then either _input
or _process
. Should input update physics? then either _input
or _physics_process
.
I'd prefer using Input
from _process
or _physics_process
, until you run into a situation where you need _input
.
By the way, the just_pressed
and just_released
methods are intended to work on both _process
and _physics_process
, they check on which one you are calling them.
On smooth motion
Either _process
or _physics_process
could be the faster one, depending on hardware and configuration. Any visual only change that happens faster than _process
will not be seen. On the other hand, if it changes any slower, then it will not appear as smooth motion.
Since Godot will execute physics according to Physics FPS, if you configure a low Physics FPS, the physic bodies appear to teleport. Plus, tunneling will be more likely to happen. For which you want to configure your RigidBody
to use continuous collision detection (set it to Cast Ray, because shape Cast Shape is not great on the current version - note: I wrote this referring to Godot 3.x).
It is possible to apply smooth motion to sprites and meshes (moving them in _process
) to follow physic bodies (which move in _physics_process
), see also smoothing-addon. You may see shapes intersect because it does not predict collisions. But that might be the price for better performance.
You might also be interested in the proposal Fixing physics timestep vs refresh rate problems (jitter), and the proposal Add object position interpolation between physics frames
On delta
Godot will try to keep stable the frequency of both _physics_process
and _process
(when VSync is enabled). However, that is not certain. Not on a machine where there are other applications running, or where you can write a code that takes too much time to run for the time budget of a frame. And thus, both need and have delta
.
There are some things that will not require you to use delta
. For example, for graphics if you use an AnimationPlayer
or Tween
, it is handled for you. Of course, AnimationPlayer
or Tween
are not only useful for graphics.
Similarly, for physics if you use force
and torque
methods of RigidBody
and its 2D counterparts, you don't have to worry about delta
.
And then on KinematicBody
and its 2D counterpart, move_and_slide
automatically applies delta
, but move_and_collide
and test_motion
doesn't. Notice that move_and_collide
and test_motion
take rel_vec
not linear_velocity
. Thus, you should multiply by delta
from _physics_process
for them to be frame independent. Which is another reason to use them in _physics_process
.