How to reinit RigidBody3D in PhysicsServer3D

Godot Version

Godot v4.2.1.stable

Question

Hello! I discovered a bug in Godot 4 related to gravity override. If position of the RigidBody3D changes (for example for teleportation), gravity will not be changed if the body was inside the Area3D. There is no such bug in Godot 3. I opened an issue about this, but no one has responded to it yet:

The error persists with any method of body teleportation. Initially I tried changing global_transform.origin, then state.transform in the _integrate_forces. I also tried freezing body while teleporting, but that doesn’t help.

It appears that the body is not being removed from overlapping bodies in PhysicsServer3D. Interestingly, when teleporting - _on_body_exited() is called, but gravity does not change to global gravity for some unknown reason.

I wouldn’t want to remove the body from the SceneTree as it would have a big impact on performance. Is there a way to “reload” the body so that it is definitely reinitialized in PhysicsServer3d? I would just call this every teleportation for the teleported body.

Sorry for the large number of edits, I didn’t understand the forum functions well. And in general I write through Google Translator :upside_down_face:

I think the physicsbodystate has a gravity variable. Maybe in the exit function you remove the area effect. Although that sounds terrible.

1 Like

Thanks for your reply!

I think the physicsbodystate has a gravity variable.

It looks like state.total_gravity only has a getter. In any case, I was unable to change gravity through it.

I tried changing space manually via this method, but it had no effect:

It also seems that after teleportation, this area ceases to change the body gravity at all, even if the gravity was changed by another Area3D to the correct one.

There doesn’t seem to be an easy workaround here :slightly_frowning_face:

I wonder if there is some Area collision logic to change forces applied that the teleport bypasses. I’ll see if I have time to look at the Godot source code later.

This is just a hunch, but what if the forces like gravity are stored per physics object. If that total_gravity is a read only that gets modified by the Area on entry. We could undo it by applying a constant force to cancel area effects.

Although I don’t know what would get updated.

In order to calculate the force use the old physics formula F=m*a
This is pseudo code but I trust that the info is available some how

# undo area gravity before or after teleport (area on exit signal?)
var  area_force_dir_vec =  area.grav_dir_vec * ( body.mass * area.grav_acc)
body.apply_constant_force( -area_force_dir_vec  ) 
1 Like

This definitely works to cancel out the effects of gravity :3

It’s a pity that the constant forces option doesn’t quite suit me, it looked promising. I’m making a game with portals and changing gravity. I’m using the gravity vector to flip the character. If no workaround will be found/this bug will not be fixed, I will most likely have to make a complete copy of the existing gravity_override system based on changing global gravity or something similar.

In any case, thanks for your help :blush:. If no one paid attention to this the bug, I would go crazy :crazy_face:

I’ve been taking a poke around the physics engine.

I found a comment that breaths a lot of confidence in to Godot’s physics

image

… The space3d is the component of the physics engine that tests for collisions. I’m trying to understand the flow of a body entering and exiting an area.

1 Like

I’m also hitting this bug. For me the repro involves having a body enter a gravity override area3d, then setting the body kinematic / freezing it and moving it out of the area.

If you look at the total_gravity param, it’s whatever the area3d set it to. Haven’t currently got a work around. I’ll post back if I find one.

Looking at the source, it’s probably that the area still exists in the bodies area list, so calling remove_area with the related area in c++ would probably fix it.

1 Like

I’ve written a script driven fix here:

It fixes my issue. I call body_clear_areas after I set my RigidBody kinematic/frozen.
I’ll clean it up and see if I can make a pull request.

but it should probably be fixed by automatically clearing body areas when bodies become kinematic

2 Likes

Looks like this might have been fixed here:

So, godot 4.3 shouldn’t need the hotfix I wrote. :slight_smile:

1 Like

Wow, I didn’t know that was already being fixed) Looks like this fix is ​​in the current RC, so I’ll wait for the next release to fix this issue. Thanks to all :blush:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.