RigidBody3D random teleporting

Godot Version

v.4.2.1.stable.mono.official [b09f793f5]

Question

I am a beginner to using Godot in 3D space and I am trying to get to know it by creating a simple space fighter sim. I started out having my player controlled as a CharacterBody3D but then converted it to a RigidBody3D in order to be able to apply forces.

Now during my trial and error on how to use that I stumbled upon strange position glitches which turned out to happen, even if I do not apply forces. After a random number of seconds the position of my RigidBody teleports to a different, yet repeatable position.
If I apply a force it changes depending on the value I set.

I have to admit that I really do not understand what I am doing wrong and I have trouble finding posts with similar issues.

Here is my node tree for my Player Object (which is to be a spacefighter)

Player [RigidBody3D]
-- Camera3D [Camera3D]
-- ShipA [Node3D imported from a Blenderfile]
-- CollisionShape3D [CollisionShape3D with a simple BoxCollider]

Here is the code which handles mouse-based steering and a simple force appliance for moving (which is currently not working, there is still some bug in force-apply - nothing happens when pushing the button, but that is another topic)

extends RigidBody3D

var direction
var scaled_mouse_pos_x
var scaled_mouse_pos_y

var mouse_range_min = 0.01
var mouse_range_max = 0.9

var rot_vel_x
var rot_vel_y

func _process(delta):
	# Throttle
	direction = Input.get_axis("ui_up", "ui_down")

	# Deactivation of add_constant_force() does not prevent glitch, but changes the "random" position
	add_constant_force(-1000 * delta * direction * transform.basis.x)
		
	# Handle mouse rotation
	scaled_mouse_pos_x = (get_viewport().get_mouse_position().x - (get_viewport().size.x / 2)) / (get_viewport().size.x / 2)
	scaled_mouse_pos_y = (get_viewport().get_mouse_position().y - (get_viewport().size.y / 2)) / (get_viewport().size.y / 2)

	if abs(scaled_mouse_pos_x) >= mouse_range_min: 
		rot_vel_x = (clampf((abs(scaled_mouse_pos_x) - mouse_range_min), 0, mouse_range_max) * sign(scaled_mouse_pos_x))
	else:
		rot_vel_x = 0
		
	if abs(scaled_mouse_pos_y) >= mouse_range_min: 
		rot_vel_y = (clampf((abs(scaled_mouse_pos_y) - mouse_range_min), 0, mouse_range_max) * sign(scaled_mouse_pos_y))
	else:
		rot_vel_y = 0

	global_rotate(Vector3(0,1,0), -rot_vel_x * delta)
	rotate_object_local(Vector3(0,0,1), -rot_vel_y * delta)

Thanks in advance!!

I’m noticing one thing in particular.

Not using _physics_process() and _integrate_forces()

The code that you’re using to add forces to your rigidbody is located within _process(). _process() runs at the same rate the game is rendered, but physics are only updated at a set rate. In other words, the update rate of the rendering and the physics are not the same. It is for this reason that most game engines have a seperate update function for physics, namely _physics_process().

_physics_process() runs at the same rate as physics are updated and so this is typically where you would add force, torque or impulses.

In addition, RigidBody3D/RigidBody2D has a separate processing function called _integrate_forces(). This function should be used whenever the goal is to directly modify the state of the rigidbody (e.g. its position, rotation, velocity etc.). Since you’re directly modifying the rotation of the object, you should be using _integrate_forces() as well.

In general, always use _physics_process() and _integrate_forces() when working with continuous physics interactions - otherwise…

Resources

P.S. Great formulation of your issue. It made it as easy as possible to debug.

Thanks for the quick and precise answer! That was indeed the issue. I simply only renamed

func _process(delta):

to

func _physics_process(delta)

Right after that gravity started working and it looks like the issue is gone.

Thanks aswell for the hint about _integrate_forces(), I will look this one up and the resources you linked.
Sometimes the Youtube tutorials are simply not as good as you expect them to be and you should then simply dive back into the good old written documentation :slight_smile:

1 Like