PhysicsTestMotionResult in Godot 4: Identifier "PhysicsTestMotionResult" not declared

By Eduardo Orellana · Updated

PhysicsTestMotionResult is called PhysicsTestMotionResult3D in Godot 4. A Godot 3 script that calls PhysicsTestMotionResult.new() fails to parse with Identifier "PhysicsTestMotionResult" not declared in the current scope; create a PhysicsTestMotionResult3D, and pass PhysicsServer3D.body_test_motion a PhysicsTestMotionParameters3D for the start transform and motion.

AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.

Intel or AMD Chromebook, with Linux turned on.

Download for macOSDownload for Windows

What Godot is checking

When GDScript loads a script it resolves every identifier. PhysicsTestMotionResult is not a class in Godot 4, so the analyzer stops with Identifier not declared in the current scope and none of the script runs.

When the project setting debug/gdscript/warnings/renamed_in_godot_4_hint is on, the analyzer looks the name up in the Godot 3 to 4 rename table and appends Did you mean to use with the new name. That table carries PhysicsTestMotionResult to PhysicsTestMotionResult3D, Physics2DTestMotionResult to PhysicsTestMotionResult2D and PhysicsServer to PhysicsServer3D.

The call changed too. In Godot 3.6, PhysicsServer.body_test_motion took the body, a from Transform, a motion Vector3, infinite_inertia and the result. In Godot 4.7.2, PhysicsServer3D.body_test_motion takes the body RID, a PhysicsTestMotionParameters3D and an optional PhysicsTestMotionResult3D, and returns true if a collision would result.

Reproduce it

A Godot 3 script that creates a PhysicsTestMotionResult to pass to body_test_motion, in a Godot 4 project. The scene is one Node with this script.

extends Node

var result = PhysicsTestMotionResult.new()

func _ready():
	print(result)

What Godot 4.7.2 prints

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Identifier "PhysicsTestMotionResult" not declared in the current scope. Did you mean to use "PhysicsTestMotionResult3D"?
   at: GDScript::reload (res://answers/physicstestmotionresult-in-godot-4/repro.gd:3)
ERROR: Failed to load script "res://answers/physicstestmotionresult-in-godot-4/repro.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)

Fix it

Create a PhysicsTestMotionResult3D, put the start transform and motion in a PhysicsTestMotionParameters3D, and pass both to PhysicsServer3D.body_test_motion. Here a sphere body 2 m up tests a 5 m drop onto a box floor whose top is at y = 0.5.

extends Node3D

func _ready() -> void:
	var floor_body := StaticBody3D.new()
	var floor_shape := CollisionShape3D.new()
	var box := BoxShape3D.new()
	box.size = Vector3(10, 1, 10)
	floor_shape.shape = box
	floor_body.add_child(floor_shape)
	add_child(floor_body)

	var body := CharacterBody3D.new()
	var body_shape := CollisionShape3D.new()
	var sphere := SphereShape3D.new()
	sphere.radius = 0.5
	body_shape.shape = sphere
	body.add_child(body_shape)
	body.position = Vector3(0, 2, 0)
	add_child(body)

	await get_tree().physics_frame

	var params := PhysicsTestMotionParameters3D.new()
	params.from = body.global_transform
	params.motion = Vector3(0, -5, 0)
	var result := PhysicsTestMotionResult3D.new()
	var hit := PhysicsServer3D.body_test_motion(body.get_rid(), params, result)
	print("collided: ", hit)
	print("travel y: ", snappedf(result.get_travel().y, 0.01))
	print("normal: ", result.get_collision_normal())
	print("collider is floor: ", result.get_collider() == floor_body)

What the fixed script prints

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

collided: true
travel y: -0.99
normal: (0.0, 1.0, 0.0)
collider is floor: true

Verified on Godot 4.7.2

Both scripts on this page were run headless on Godot 4.7.2 (4.7.2.stable.mono.official.ed1daf0bf) on 6 October 2026, and the output above is what Godot printed, unedited.

Where the check lives in Godot's source: [gdscript_analyzer.cpp lines 4679 to 4687, the message and the rename hint](https://github.com/godotengine/godot/blob/4.7.2-stable/modules/gdscript/gdscript_analyzer.cpp#L4679), [renames_map_3_to_4.cpp line 1576, PhysicsTestMotionResult to PhysicsTestMotionResult3D](https://github.com/godotengine/godot/blob/4.7.2-stable/editor/project_upgrade/renames_map_3_to_4.cpp#L1576), [PhysicsServer3D.body_test_motion class reference](https://github.com/godotengine/godot/blob/4.7.2-stable/doc/classes/PhysicsServer3D.xml#L692), [PhysicsTestMotionResult3D class reference](https://github.com/godotengine/godot/blob/4.7.2-stable/doc/classes/PhysicsTestMotionResult3D.xml), [PhysicsServer.body_test_motion in Godot 3.6](https://github.com/godotengine/godot/blob/3.6-stable/doc/classes/PhysicsServer.xml#L597).

Questions

What is the 2D version called?
Physics2DTestMotionResult is PhysicsTestMotionResult2D in Godot 4, and it goes with PhysicsServer2D.body_test_motion and PhysicsTestMotionParameters2D.
Where did infinite_inertia and exclude go?
Godot 4.7.2's body_test_motion takes no infinite_inertia argument. Exclusions are properties of PhysicsTestMotionParameters3D: exclude_bodies takes RIDs and exclude_objects takes instance IDs. It also has margin, max_collisions, collide_separation_ray and recovery_as_collision.
What can I read from PhysicsTestMotionResult3D?
get_travel and get_remainder for the motion, get_collision_count, and per collision get_collider, get_collider_id, get_collider_rid, get_collider_shape, get_collider_velocity, get_collision_point, get_collision_normal, get_collision_depth and the safe and unsafe fractions.