Advanced physics interpolation
Although the previous instructions will give satisfactory results in a lot of games, in some cases you will want to go a stage further to get the best possible results and the smoothest possible experience.
Exceptions to automatic physics interpolation
Node (or branch of the SceneTree), and have the finer control of performing interpolation manually. Node.physics_interpolation_mode property which is present in all Nodes. If you for example, turn off interpolation for a Node, the children will recursively also be affected (as they default to inheriting the parent setting). This means you can easily disable interpolation for an entire subscene. The most common situation where you may want to perform your own interpolation is Cameras.
Cameras
Camera can use automatic interpolation just like any other node. However, for best results, especially at low physics tick rates, it is recommended that you take a manual approach to Camera interpolation.
_process, and following an interpolated target manually.
Manual Camera interpolation
Ensure the Camera is using global coordinate space global space rather than inheriting the transform of a moving parent. This is because feedback can occur between the movement of a parent node of a Camera and the movement of the Camera Node itself, which can mess up the interpolation. There are two ways of doing this: 1.
- Spatial.set_as_toplevel and set this to
true, which will make the Camera ignore the transform of its parent.Typical example
look_atfunction in the Camera every frame in_process()to look at a target node (such as the player).get_global_transform()on a Camera “target” Node, this transform will only focus the Camera on the target at the current physics tick. This is not what we want, as the Camera will jump about on each physics tick as the target moves. Even though the Camera may be updated each frame, this does not help give smooth motion if the target is only changing each physics tick.get_global_transform_interpolated()
interpolated position, i.e. the position at which the target will be rendered. Spatial.get_global_transform_interpolated function. This acts exactly like getting Spatial.global_transform but it gives you the interpolated transform (during a_process()call). Importantget_global_transform_interpolated()should only be used once or twice for special cases such as Cameras. It should not be used all over the place in your code (both for performance reasons, and to give correct gameplay). Note_physics_process(). In game logic you should be callingget_global_transform()orget_transform(), which will give the current physics transform (in global or local space respectively), which is usually what you will want for gameplay code.Example manual Camera script
Here is an example of a simple fixed Camera which follows an interpolated target:extends Camera# Node that the camera will followvar _target# We will smoothly lerp to follow the target# rather than follow exactlyvar _target_pos : Vector3 = Vector3()func _ready() -> void: # Find the target node _target = get_node("../Player") # Turn off automatic physics interpolation for the Camera, # we will be doing this manually set_physics_interpolation_mode(Node.PHYSICS_INTERPOLATION_MODE_OFF)func _process(delta: float) -> void: # Find the current interpolated transform of the target var tr : Transform = _target.get_global_transform_interpolated() # Provide some delayed smoothed lerping towards the target position _target_pos = lerp(_target_pos, tr.origin, min(delta, 1.0)) # Fixed camera position, but it will follow the target look_at(_target_pos, Vector3(0, 1, 0))
Mouse look
Mouse look is a very common way of controlling Cameras. But there is a problem. Unlike keyboard input which can be sampled periodically on the physics tick, mouse move events can come in continuously. The Camera will be expected to react and follow these mouse movements on the next frame, rather than waiting until the next physics tick. Node.physics_interpolation_mode) and directly apply the mouse input to the Camera rotation, rather than apply it in_physics_process. Sometimes, especially with Cameras, you will want to use a combination of interpolation and non-interpolation:
- Spatial.get_global_transform_interpolated), but control the Camera rotation from mouse look without interpolation.
- Spatial.get_global_transform_interpolated, but position the camera using mouse look without interpolation.
There are many permutations and variations of Camera types, but it should be clear that in many cases, disabling automatic physics interpolation and handling this yourself can give a better result.
Disabling interpolation on other nodes
Although Cameras are the most common example, there are a number of cases when you may wish other nodes to control their own interpolation, or be non-interpolated. Consider for example, a player in a top view game whose rotation is controlled by mouse look. Disabling physics rotation allows the player rotation to match the mouse in real-time.MultiMeshes
per-instance basis. You should explore these functions if you are using interpolated MultiMeshes. - MultiMesh.reset_instance_physics_interpolation
- MultiMesh.set_as_bulk_array_interpolated MultiMesh documentation.
