How to use PhysicsServer3D.body_test_motion

Godot Version

V4.2.1

Question

I have been scratching my head on how to tell where my character will land before I hit the ground for days now and I think I found a solution but I don’t know how to use it properly.

I think that the PhysicsServer3D method “body_test_motion” will get me the results I want

From what I understand within the method I need to pass a RID, a Motion and then get my result in the form of a Vector3 Collision point (get_collision_point).

What exactly is a RID? I’m assuming its my character or whatever I am moving but not exactly sure how to write it properly
How would I give it my motion? I am assuming my velocity?
And can I use this to tell where my character will land and if so how do you properly write this in gdscript?

If possible a gdscript example of how this method is written would be amazing

To the future people here also in need of help with using this function it’s posible to use by doing it like this

define a PhysicsTestMotionParameters3D varible in the script, and instanciate it in the ready function, or where ever you’re gonna use it and make sure to define the motion property in the PhysicsTestMotionParameters3D .

having done that just pass it into the function like so

PhysicsServer3D.body_test_motion(get_rid(), your_PhysicsTestMotion)

the important part that they dont tell you in the documentation is to keep updating the PhysicsTestMotionParameters3D parameter called “from”. which is where the motion begins from. I recomend updating it just whenever you’re gonna run the function but fell free to do whatever otherwise you will end up having a never changing result from the function.

me later here also remember it’s gotta be global_transform

I figured it out heres the code

#Determines where the player will land when airborne
func _GroundPrediction(delta):
	var max_points = 300 #The distance of how far the prediction will go
	var exclude_body: Array[RID] = [player.get_rid()] #Tells the prediction rays what to ignore ### UPDATE THIS WHEN ENEMIES OR OTHER OBJECTS ARE ADDED ###
	var pos = player.global_position #Tells the prediction to start at the player
	var vel = player.velocity #Tells the prediction which way the player is going
	var collision # Creates a variable that holds prediction collision information
	for i in max_points: # The loop that iterates the predictions distance and stops when a collision is made
		if predictReset == true: # Stops the script from continueing if the player is already airborne or from going past the point of the collision that is made
			vel.y -= (player.gravity * 2) * delta # Copies the players movement velocity and predicts where it will go based on gravity and direction
			pos += vel * delta # The players future positions while airborne
			#Grabs the world state and projects a ray for each position to find where the player will land
			var direct_state = player.get_world_3d().direct_space_state
			collision = direct_state.intersect_ray(PhysicsRayQueryParameters3D.create(pos + Vector3(0,1,0), pos + Vector3(0,-0.1,0), 3, exclude_body))
			# Visuals for testing
			##var test = test_capsule.instantiate() 
			##add_child(test)
			##test.global_position = pos + Vector3(0,1,0)
		# Stops the prediction if a collision is made
		if collision and predictReset == true: # Plays if a collision is made and will only grab the collision information once
			##var test2 = test_capsule.instantiate()
			##add_child(test2)
			##test2.global_position = collision["position"]
			player.normal = collision["normal"]
			print(collision["normal"])
			##print(collision["position"])
			predictReset = false # Stops the prediction position update and resets for when the player is airborne again
			break