Port physics interpolation docs from 3.6

This commit is contained in:
skyace65
2024-12-01 09:30:44 -05:00
parent 53ce972738
commit 6b4a2c9801
11 changed files with 658 additions and 0 deletions

View File

@@ -19,3 +19,4 @@ Physics
collision_shapes_3d
large_world_coordinates
troubleshooting_physics_issues
interpolation/index

View File

@@ -0,0 +1,69 @@
.. _doc_2d_and_3d_physics_interpolation:
2D and 3D physics interpolation
===============================
Generally 2D and 3D physics interpolation work in very similar ways. However, there
are a few differences, which will be described here.
Global versus local interpolation
---------------------------------
- In 3D, physics interpolation is performed *independently* on the **global
transform** of each 3D instance.
- In 2D by contrast, physics interpolation is performed on the **local transform**
of each 2D instance.
This has some implications:
- In 3D, it is easy to turn interpolation on and off at the level of each ``Node``,
via the ``physics_interpolation_mode`` property in the Inspector, which can be
set to ``On``, ``Off``, or ``Inherited``.
.. figure:: img/physics_interpolation_mode.webp
:align: center
- However this means that in 3D, pivots that occur in the ``SceneTree`` (due to
parent child relationships) can only be interpolated **approximately** over the
physics tick. In most cases this will not matter, but in some situations the
interpolation can look slightly wrong.
- In 2D, interpolated local transforms are passed down to children during
rendering. This means that if a parent is set to ``physics_interpolation_mode``
``On``, but the child is set to ``Off``, the child will still be interpolated if
the parent is moving. *Only the child's local transform is uninterpolated.*
Controlling the on / off behavior of 2D nodes therefore requires a little more
thought and planning.
- On the positive side, pivot behavior in the scene tree is perfectly preserved
during interpolation in 2D, which gives super smooth behaviour.
Resetting physics interpolation
-------------------------------
Whenever objects are moved to a completely new position, and interpolation is not
desired (so as to prevent a "streaking" artefact), it is the responsibility of the
user to call ``reset_physics_interpolation()``.
The good news is that in 2D, this is automatically done for you when nodes first
enter the tree. This reduces boiler plate, and reduces the effort required to get
an existing project working.
.. note:: If you move objects *after* adding to the scene tree, you will still need
to call ``reset_physics_interpolation()`` as with 3D.
2D Particles
------------
Currently only ``CPUParticles2D`` are supported for physics interpolation in 2D. It
is recommended to use a physics tick rate of at least 20-30 ticks per second to
keep particles looking fluid.
``Particles2D`` (GPU particles) are not yet interpolated, so for now it is
recommended to convert to ``CPUParticles2D`` (but keep a backup of your
``Particles2D`` in case we get these working).
Other
-----
- ``get_global_transform_interpolated()`` - this is currently only available for 3D.
- ``MultiMeshes`` - these should be supported in both 2D and 3D.

View File

@@ -0,0 +1,174 @@
.. _doc_advanced_physics_interpolation:
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
---------------------------------------------
Even with physics interpolation active, there may be some local situations where
you would benefit from disabling automatic interpolation for a
:ref:`Node<class_Node>` (or branch of the :ref:`SceneTree<class_SceneTree>`), and
have the finer control of performing interpolation manually.
This is possible using the :ref:`Node.physics_interpolation_mode<class_Node_property_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
~~~~~~~
In many cases, a :ref:`Camera3D<class_Camera3D>` 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.
This is because viewers are very sensitive to camera movement. For instance, a
Camera3D that realigns slightly every 1/10th of a second (at 10tps tick rate) will
often be noticeable. You can get a much smoother result by moving the camera each
frame in ``_process``, and following an interpolated target manually.
Manual camera interpolation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ensure the camera is using global coordinate space
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The very first step when performing manual camera interpolation is to make sure the
Camera3D transform is specified in *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 Camera3D and the movement of the camera Node itself,
which can mess up the interpolation.
There are two ways of doing this:
1) Move the Camera3D so it is independent on its own branch, rather than being a child of a moving object.
.. image:: img/fti_camera_worldspace.webp
2) Call :ref:`Node3D.top_level<class_Node3D_property_top_level>` and set this to ``true``, which will make the Camera ignore the transform of its parent.
Typical example
^^^^^^^^^^^^^^^
A typical example of a custom approach is to use the ``look_at`` function in the
Camera3D every frame in ``_process()`` to look at a target node (such as the player).
But there is a problem. If we use the traditional ``get_global_transform()`` on a
Camera3D "target" node, this transform will only focus the Camera3D 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()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
What we really want to focus the camera on, is not the position of the target on
the physics tick, but the *interpolated* position, i.e. the position at which the
target will be rendered.
We can do this using the :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_get_global_transform_interpolated>`
function. This acts exactly like getting :ref:`Spatial.global_transform<class_Node3D_property_global_transform>`
but it gives you the *interpolated* transform (during a ``_process()`` call).
.. important:: ``get_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:: Aside from exceptions like the camera, in most cases, your game logic
should be in ``_physics_process()``. In game logic you should be calling
``get_global_transform()`` or ``get_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:
.. code-block:: gdscript
extends Camera3D
# Node that the camera will follow
var _target
# We will smoothly lerp to follow the target
# rather than follow exactly
var _target_pos : Vector3 = Vector3()
func _ready() -> void:
# Find the target node
_target = get_node("../Player")
# Turn off automatic physics interpolation for the Camera3D,
# 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.
In this situation, it can be better to disable physics interpolation for the camera
node (using :ref:`Node.physics_interpolation_mode<class_Node_property_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:
* A first person camera may position the camera at a player location (perhaps using :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_get_global_transform_interpolated>`), but control the Camera rotation from mouse look *without* interpolation.
* A third person camera may similarly determine the look at (target location) of the camera using :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_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
~~~~~~~~~~~
Although most visual Nodes follow the single Node single visual instance paradigm,
MultiMeshes can control several instances from the same Node. Therefore, they have
some extra functions for controlling interpolation functionality on a
*per-instance* basis. You should explore these functions if you are using
interpolated MultiMeshes.
- :ref:`MultiMesh.reset_instance_physics_interpolation<class_MultiMesh_method_reset_instance_physics_interpolation>`
- :ref:`MultiMesh.set_buffer_interpolated<class_MultiMesh_method_set_buffer_interpolated>`
Full details are in the :ref:`MultiMesh<class_MultiMesh>` documentation.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,14 @@
.. _doc_physics_interpolation:
Physics Interpolation
=====================
.. toctree::
:maxdepth: 1
:name: toc-physics-interpolation
physics_interpolation_quick_start_guide
physics_interpolation_introduction
using_physics_interpolation
advanced_physics_interpolation
2d_and_3d_physics_interpolation

View File

@@ -0,0 +1,232 @@
.. _doc_physics_interpolation_introduction:
Introduction
============
Physics ticks and rendered frames
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
One key concept to understand in Godot is the distinction between physics ticks
(sometimes referred to as iterations or physics frames), and rendered frames. The
physics proceeds at a fixed tick rate (set in :ref:`Project Settings > Physics > Common > Physics Tick per Second<class_ProjectSettings_property_physics/common/physics_ticks_per_second>`),
which defaults to 60 ticks per second.
However, the engine does not necessarily **render** at the same rate. Although many
monitors refresh at 60 Hz (cycles per second), many refresh at completely different
frequencies (e.g. 75 Hz, 144 Hz, 240 Hz or more). Even though a monitor may be able
to show a new frame e.g. 60 times a second, there is no guarantee that the CPU and
GPU will be able to *supply* frames at this rate. For instance, when running with
V-Sync, the computer may be too slow for 60 and only reach the deadlines for 30
FPS, in which case the frames you see will change at 30 FPS (resulting in
stuttering).
But there is a problem here. What happens if the physics ticks do not coincide with
frames? What happens if the physics tick rate is out of phase with the frame rate?
Or worse, what happens if the physics tick rate is *lower* than the rendered frame
rate?
This problem is easier to understand if we consider an extreme scenario. If you set
the physics tick rate to 10 ticks per second, in a simple game with a rendered
frame rate of 60 FPS. If we plot a graph of the positions of an object against the
rendered frames, you can see that the positions will appear to "jump" every 1/10th
of a second, rather than giving a smooth motion. When the physics calculates a new
position for a new object, it is not rendered in this position for just one frame,
but for 6 frames.
.. image:: img/fti_graph_fixed_ticks.webp
This jump can be seen in other combinations of tick / frame rate as glitches, or
jitter, caused by this staircasing effect due to the discrepancy between physics
tick time and rendered frame time.
What can we do about frames and ticks being out of sync?
--------------------------------------------------------
Lock the tick / frame rate together?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The most obvious solution is to get rid of the problem, by ensuring there is a
physics tick that coincides with every frame. This used to be the approach on old
consoles and fixed hardware computers. If you know that every player will be using
the same hardware, you can ensure it is fast enough to calculate ticks and frames
at e.g. 50 FPS, and you will be sure it will work great for everybody.
However, modern games are often no longer made for fixed hardware. You will often
be planning to release on desktop computers, mobiles, and more. All of which have
huge variations in performance, as well as different monitor refresh rates. We need
to come up with a better way of dealing with the problem.
Adapt the tick rate?
^^^^^^^^^^^^^^^^^^^^
Instead of designing the game at a fixed physics tick rate, we could allow the tick
rate to scale according to the end users hardware. We could for example use a fixed
tick rate that works for that hardware, or even vary the duration of each physics
tick to match a particular frame duration.
This works, but there is a problem. Physics (*and game logic*, which is often also
run in the ``_physics_process``) work best and most consistently when run at a
**fixed**, predetermined tick rate. If you attempt to run a racing game physics
that has been designed for 60 TPS (ticks per second) at e.g. 10 TPS, the physics
will behave completely differently. Controls may be less responsive, collisions /
trajectories can be completely different. You may test your game thoroughly at 60
TPS, then find it breaks on end users machines when it runs at a different tick
rate.
This can make quality assurance difficult with hard to reproduce bugs, especially
in AAA games where problems of this sort can be very costly. This can also be
problematic for multiplayer games for competitive integrity, as running the game at
certain tick rates may be more advantageous than others.
Lock the tick rate, but use interpolation to smooth frames in between physics ticks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This has become one of the most popular approaches to deal with the problem,
although it is optional and disabled by default.
We have established that the most desirable physics/game logic arrangement for
consistency and predictability is a physics tick rate that is fixed at design-time.
The problem is the discrepancy between the physics position recorded, and where we
"want" a physics object to be shown on a frame to give smooth motion.
The answer turns out to be simple, but can be a little hard to get your head around
at first.
Instead of keeping track of just the current position of a physics object in the
engine, we keep track of *both the current position of the object, and the previous
position* on the previous physics tick.
Why do we need the previous position *(in fact the entire transform, including
rotation and scaling)*? By using a little math magic, we can use **interpolation**
to calculate what the transform of the object would be between those two points, in
our ideal world of smooth continuous movement.
.. image:: img/fti_graph_interpolated.webp
Linear interpolation
^^^^^^^^^^^^^^^^^^^^
The simplest way to achieve this is linear interpolation, or lerping, which you may
have used before.
Let us consider only the position, and a situation where we know that the previous
physics tick X coordinate was 10 units, and the current physics tick X coordinate
is 30 units.
.. note:: Although the maths is explained here, you do not have to worry about the
details, as this step will be performed for you. Under the hood, Godot
may use more complex forms of interpolation, but linear interpolation is
the easiest in terms of explanation.
The physics interpolation fraction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If our physics ticks are happening 10 times per second (for this example), what
happens if our rendered frame takes place at time 0.12 seconds? We can do some math
to figure out where the object would be to obtain a smooth motion between the two
ticks.
First of all, we have to calculate how far through the physics tick we want the
object to be. If the last physics tick took place at 0.1 seconds, we are 0.02
seconds *(0.12 - 0.1)* through a tick that we know will take 0.1 seconds (10 ticks
per second). The fraction through the tick is thus:
.. code-block:: gdscript
fraction = 0.02 / 0.10
fraction = 0.2
This is called the **physics interpolation fraction**, and is handily calculated
for you by Godot. It can be retrieved on any frame by calling :ref:`Engine.get_physics_interpolation_fraction<class_Engine_method_get_physics_interpolation_fraction>`.
Calculating the interpolated position
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once we have the interpolation fraction, we can insert it into a standard linear
interpolation equation. The X coordinate would thus be:
.. code-block:: gdscript
x_interpolated = x_prev + ((x_curr - x_prev) * 0.2)
So substituting our ``x_prev`` as 10, and ``x_curr`` as 30:
.. code-block:: gdscript
x_interpolated = 10 + ((30 - 10) * 0.2)
x_interpolated = 10 + 4
x_interpolated = 14
Let's break that down:
- We know the X starts from the coordinate on the previous tick (``x_prev``) which
is 10 units.
- We know that after the full tick, the difference between the current tick and the
previous tick will have been added (``x_curr - x_prev``) (which is 20 units).
- The only thing we need to vary is the proportion of this difference we add,
according to how far we are through the physics tick.
.. note:: Although this example interpolates the position, the same thing can be
done with the rotation and scale of objects. It is not necessary to know
the details as Godot will do all this for you.
Smoothed transformations between physics ticks?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Putting all this together shows that it should be possible to have a nice smooth
estimation of the transform of objects between the current and previous physics
tick.
But wait, you may have noticed something. If we are interpolating between the
current and previous ticks, we are not estimating the position of the object *now*,
we are estimating the position of the object in the past. To be exact, we are
estimating the position of the object *between 1 and 2 ticks* into the past.
In the past
^^^^^^^^^^^
What does this mean? This scheme does work, but it does mean we are effectively
introducing a delay between what we see on the screen, and where the objects
*should* be.
In practice, most people won't notice this delay, or rather, it is typically not
*objectionable*. There are already significant delays involved in games, we just
don't typically notice them. The most significant effect is there can be a slight
delay to input, which can be a factor in fast twitch games. In some of these fast
input situations, you may wish to turn off physics interpolation and use a
different scheme, or use a high tick rate, which mitigates these delays.
Why look into the past? Why not predict the future?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There is an alternative to this scheme, which is: instead of interpolating between
the previous and current tick, we use maths to *extrapolate* into the future. We
try to predict where the object *will be*, rather than show it where it was. This
can be done and may be offered as an option in future, but there are some
significant downsides:
- The prediction may not be correct, especially when an object collides with
another object during the physics tick.
- Where a prediction was incorrect, the object may extrapolate into an "impossible"
position, like inside a wall.
- Providing the movement speed is slow, these incorrect predictions may not be too
much of a problem.
- When a prediction was incorrect, the object may have to jump or snap back onto
the corrected path. This can be visually jarring.
Fixed timestep interpolation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In Godot this whole system is referred to as physics interpolation, but you may
also hear it referred to as **"fixed timestep interpolation"**, as it is
interpolating between objects moved with a fixed timestep (physics ticks per
second). In some ways the second term is more accurate, because it can also be used
to interpolate objects that are not driven by physics.
.. tip:: Although physics interpolation is usually a good choice, there are
exceptions where you may choose not to use Godot's built-in physics
interpolation (or use it in a limited fashion). An example category is
internet multiplayer games. Multiplayer games often receive tick or timing
based information from other players or a server and these may not
coincide with local physics ticks, so a custom interpolation technique can
often be a better fit.

View File

@@ -0,0 +1,14 @@
.. _doc_physics_interpolation_quick_start_guide:
Quick start guide
=================
- Turn on physics interpolation: :ref:`Project Settings > Physics > Common > Physics Interpolation<class_ProjectSettings_property_physics/common/physics_interpolation>`
- Make sure you move objects and run your game logic in ``_physics_process()``
rather than ``_process()``. This includes moving objects directly *and
indirectly* (by e.g. moving a parent, or using another mechanism to automatically
move nodes).
- Be sure to call :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`
on nodes *after* you first position or teleport them, to prevent "streaking".
- Temporarily try setting :ref:`Project Settings > Physics > Common > Physics Tick per Second<class_ProjectSettings_property_physics/common/physics_ticks_per_second>`
to 10 to see the difference with and without interpolation.

View File

@@ -0,0 +1,154 @@
.. _doc_using_physics_interpolation:
Using physics interpolation
===========================
How do we incorporate physics interpolation into a Godot game? Are there any
caveats?
We have tried to make the system as easy to use as possible, and many existing
games will work with few changes. That said there are some situations which require
special treatment, and these will be described.
Turn on the physics interpolation setting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first step is to turn on physics interpolation in :ref:`ProjectSettings.physics/common/physics_interpolation<class_ProjectSettings_property_physics/common/physics_interpolation>`.
You can now run your game.
It is likely that nothing looks hugely different, particularly if you are running
physics at 60 TPS or a multiple of it. However, quite a bit more is happening
behind the scenes.
.. tip::
To convert an existing game to use interpolation, it is highly recommended that
you temporarily set :ref:`ProjectSettings.physics/common/physics_ticks_per_second<class_ProjectSettings_property_physics/common/physics_ticks_per_second>`
to a low value such as 10, which will make interpolation problems more obvious.
Move (almost) all game logic from _process to _physics_process
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The most fundamental requirement for physics interpolation (which you may be doing
already) is that you should be moving and performing game logic on your objects
within ``_physics_process`` (which runs at a physics tick) rather than ``_process``
(which runs on a rendered frame). This means your scripts should typically be doing
the bulk of their processing within ``_physics_process``, including responding to
input and AI.
Setting the transform of objects only within physics ticks allows the automatic
interpolation to deal with transforms *between* physics ticks, and ensures the game
will run the same whatever machine it is run on. As a bonus, this also reduces CPU
usage if the game is rendering at high FPS, since AI logic (for example) will no
longer run on every rendered frame.
.. note:: If you attempt to set the transform of interpolated objects *outside* the
physics tick, the calculations for the interpolated position will be
incorrect, and you will get jitter. This jitter may not be visible on
your machine, but it *will* occur for some players. For this reason,
setting the transform of interpolated objects should be avoided outside
of the physics tick. Godot will attempt to produce warnings in the editor
if this case is detected.
.. tip:: This is only a *soft rule*. There are some occasions where you might want
to teleport objects outside of the physics tick (for instance when
starting a level, or respawning objects). Still, in general, you should be
applying transforms from the physics tick.
Ensure that all indirect movement happens during physics ticks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Consider that in Godot, Nodes can be moved not just directly in your own scripts,
but also by automatic methods such as tweening, animation, and navigation. All
these methods should also have their timing set to operate on the physics tick
rather than each frame ("idle"), **if** you are using them to move objects (*these
methods can also be used to control properties that are not interpolated*).
.. note:: Also consider that nodes can be moved not just by moving themselves, but
also by moving parent nodes in the :ref:`SceneTree<class_SceneTree>`. The
movement of parents should therefore also only occur during physics ticks.
Choose a physics tick rate
^^^^^^^^^^^^^^^^^^^^^^^^^^
When using physics interpolation, the rendering is decoupled from physics, and you
can choose any value that makes sense for your game. You are no longer limited to
values that are multiples of the user's monitor refresh rate (for stutter-free
gameplay if the target FPS is reached).
As a rough guide:
.. csv-table::
:header: "Low tick rates (10-30)", "Medium tick rates (30-60)", "High tick rates (60+)"
:widths: 20, 20, 20
"Better CPU performance","Good physics behavior in complex scenes","Good with fast physics"
"Add some delay to input","Good for first person games","Good for racing games"
"Simple physics behaviour"
.. note:: You can always change the tick rate as you develop, it is as simple as
changing the project setting.
Call ``reset_physics_interpolation()`` when teleporting objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Most of the time, interpolation is what you want between two physics ticks.
However, there is one situation in which it may *not* be what you want. That is
when you are initially placing objects, or moving them to a new location. Here, you
don't want a smooth motion between where the object was (e.g. the origin) and the
initial position - you want an instantaneous move.
The solution to this is to call the :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`
function. What this function does under the hood is set the internally stored
*previous transform* of the object to be equal to the *current transform*. This
ensures that when interpolating between these two equal transforms, there will be
no movement.
Even if you forget to call this, it will usually not be a problem in most
situations (especially at high tick rates). This is something you can easily leave
to the polishing phase of your game. The worst that will happen is seeing a
streaking motion for a frame or so when you move them - you will know when you need
it!
There are actually two ways to use ``reset_physics_interpolation()``:
*Standing start (e.g. player)*
1) Set the initial transform
2) Call ``reset_physics_interpolation()``
The previous and current transforms will be identical, resulting in no initial
movement.
*Moving start (e.g. bullet)*
1) Set the initial transform
2) Call ``reset_physics_interpolation()``
3) Immediately set the transform expected after the first tick of motion
The previous transform will be the starting position, and the current transform
will act as though a tick of simulation has already taken place. This will
immediately start moving the object, instead of having a tick delay standing still.
.. important:: Make sure you set the transform and call
``reset_physics_interpolation()`` in the correct order as shown
above, otherwise you will see unwanted "streaking".
Testing and debugging tips
--------------------------
Even if you intend to run physics at 60 TPS, in order to thoroughly test your
interpolation and get the smoothest gameplay, it is highly recommended to
temporarily set the physics tick rate to a low value such as 10 TPS.
The gameplay may not work perfectly, but it should enable you to more easily see
cases where you should be calling :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`,
or where you should be using your own custom interpolation on e.g. a
:ref:`Camera3D<class_Camera3D>`. Once you have these cases fixed, you can set the
physics tick rate back to the desired setting.
The other great advantage to testing at a low tick rate is you can often notice
other game systems that are synchronized to the physics tick and creating glitches
which you may want to work around. Typical examples include setting animation blend
values, which you may decide to set in ``_process()`` and interpolate manually.