Godot 3 to 4 rename
PhysicsDirectBodyState in Godot 4: it is PhysicsDirectBodyState3D now
PhysicsDirectBodyState is PhysicsDirectBodyState3D in Godot 4.7.2, and RigidBody is RigidBody3D. As a type annotation the old name fails with Could not find type, an error that carries no rename hint, so type the callback _integrate_forces(state: PhysicsDirectBodyState3D).
What Godot prints
A rigid body with the Godot 3 type on its _integrate_forces parameter.
extends RigidBody3D
func _integrate_forces(state: PhysicsDirectBodyState):
print(state.linear_velocity)
SCRIPT ERROR: Parse Error: Could not find type "PhysicsDirectBodyState" in the current scope.
at: GDScript::reload (res://answers/physicsdirectbodystate-in-godot-4/repro.gd:3)
ERROR: Failed to load script "res://answers/physicsdirectbodystate-in-godot-4/repro.gd" with error "Parse error".
at: load (modules/gdscript/gdscript_resource_format.cpp:46)The fix
The same callback typed with PhysicsDirectBodyState3D. It prints the state once, after half a second of falling.
extends RigidBody3D
var steps := 0
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
steps += 1
if steps == 30:
print(state.get_class(), " is a PhysicsDirectBodyState3D: ", state is PhysicsDirectBodyState3D)
print("step ", snappedf(state.step, 0.0001), ", gravity ", state.total_gravity, ", velocity ", state.linear_velocity.snappedf(0.01))
GodotPhysicsDirectBodyState3D is a PhysicsDirectBodyState3D: true
step 0.0167, gravity (0.0, -9.8, 0.0), velocity (0.0, -4.78, 0.0)Why it happens
Here the old name is a type annotation. The analyzer resolves a script's types when it loads, finds no PhysicsDirectBodyState, and the script fails to parse. The editor adds its rename hint to errors about an unknown identifier or function call; the type lookup's error has none.
The table maps PhysicsDirectBodyState to PhysicsDirectBodyState3D, Physics2DDirectBodyState to PhysicsDirectBodyState2D, and RigidBody to RigidBody3D.
At run time the state is an object of the physics engine's own class, GodotPhysicsDirectBodyState3D in this run, which is a PhysicsDirectBodyState3D. Type the parameter with the base class, as the fix does.
The fix read the state on its 30th call: step is the timestep used for the simulation, 1/60 s here; total_gravity is the gravity applied to the body; linear_velocity is in units per second.
Sources
- renames_map_3_to_4.cpp line 1572, PhysicsDirectBodyState to PhysicsDirectBodyState3D
- renames_map_3_to_4.cpp lines 1565 and 1588, Physics2DDirectBodyState and RigidBody
- gdscript_analyzer.cpp line 904, Could not find type, with no hint
- gdscript_analyzer.cpp line 4687, the identifier error that does carry the hint
- PhysicsDirectBodyState3D class reference
- RigidBody3D._integrate_forces
Run on Godot 4.7.2, .