Physics does not work directly through the PhysicServer3D ( С++ )

Godot Version

Godot 4.3 stable , godot-cpp 4.3 stable

Question

Physics does not work directly through the PhysicServer3D. ( С++ )

Hello everyone!

For the third day now I’ve been trying to understand why my C++ code doesn’t work. I tried to use a PhysicServer3D directly. However, no attempts helped me make a simple sphere move or at least fall.

I’ve already studied several topics on the forum. It didn’t help me.
Samantha’s topic was very useful, but unfortunately there was no result =(

At first I used Flecs systems to access the PhysicServer3D. I thought maybe it was a lambda function or multithreading issue, but now I can’t get even the simplest code to work as expected.

So, this is simple Node3D class, nothing more now.

cpp
void PhysicsManager::_ready()
{
    test_body = ps->body_create();
    sphere = ps->sphere_shape_create();
    space = get_world_3d()->get_space();

    ps->shape_set_data(sphere, 0.5f);

    ps->body_set_space(test_body, space);
    ps->body_add_shape(test_body, sphere);
    ps->body_set_shape_transform(test_body, 0, Transform3D());
    ps->body_set_mode(test_body, PhysicsServer3D::BODY_MODE_RIGID_LINEAR);
    ps->body_set_param(test_body, PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, 1.0f);
    ps->body_set_param(test_body, PhysicsServer3D::BODY_PARAM_MASS, 10.0f);
    ps->body_set_collision_layer(test_body, 1);

    ps->body_set_state(test_body,PhysicsServer3D::BODY_STATE_CAN_SLEEP, false);

    Transform3D b_tr = get_global_transform().translated(Vector3(0.0f, 10.0f, 0.0f));
    ps->body_set_state(test_body, PhysicsServer3D::BODY_STATE_TRANSFORM, b_tr);
    ps->body_set_state(test_body, PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, Vector3(0.1f, 0.0f, 0.05f));
}

void PhysicsManager::_physics_process(double delta)
{
    if(running)
    {
        ps->body_add_constant_central_force(test_body, Vector3(0.0f, 0.25f, 0.0f));

        Transform3D body_transform = ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_TRANSFORM);
        UtilityFunctions::print(body_transform);
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_SLEEPING));
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY));

    }

}

I tried almost all parameters, maybe it will help: MASS, LINEAR_VELOCITY, GRAVITY_SCALE, _set_collision_layer

this is log

log
Godot Engine v4.3.stable.arch_linux - https://godotengine.org
Vulkan 1.2.180 - Forward+ - Using Device #0: AMD - AMD Radeon RX 580 Series

_ready
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
clearing
WARNING: 1 RIDs in Godot Jolt were found to not have been freed. This is likely caused by orphaned nodes. If not, consider reporting this issue.

The body just hangs at a height of 10 meters and that’s it.

I’m not a C++ pro at all. I might miss something, so I apologize if it turns out to be some really stupid mistake. =)

Hi there!

I was able to get my physics stuff to work the way that I wanted it to, so perhaps I can help! I can’t post the full solution since it’s going to be used as an exercise and potentially an assignment for other students in my program at school.

To assist me in testing your code, can you send me or post the header file for your PhysicsManager? I think this is my first time trying to help on the forum, so I’m not sure if there is proper etiquette.

2 Likes

Hi! that would be really cool of you =)
Well Ok, lets try it.

This is hpp

hpp
#ifndef PHYSICS_MANAGER_HPP
#define PHYSICS_MANAGER_HPP

#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/classes/physics_server3d.hpp>
#include <godot_cpp/classes/sphere_shape3d.hpp>
#include <godot_cpp/classes/world3d.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

#include <global_flecs.hpp>
#include <components.hpp>

using namespace godot;

class PhysicsManager : public Node3D 
{
    GDCLASS(PhysicsManager, Node3D);

protected:
    static void _bind_methods();

public:

    RID space{};
    PhysicsServer3D* ps = PhysicsServer3D::get_singleton();
    RID sphere{};

    RID test_body{};
    bool running = false;

    void _ready();
    void _physics_process(double delta);

    void set_running(bool p_running);
    bool is_running() const;

    PhysicsManager() = default;
    ~PhysicsManager() = default;
};

#endif

And cpp

cpp
#include <physics_manager.hpp>

void PhysicsManager::_bind_methods()
{
    ClassDB::bind_method(D_METHOD("set_running", "running"), &PhysicsManager::set_running);
    ClassDB::bind_method(D_METHOD("is_running"), &PhysicsManager::is_running);

    ADD_PROPERTY(PropertyInfo(Variant::BOOL, "running"), "set_running", "is_running");
}

void PhysicsManager::_ready()
{
    test_body = ps->body_create();
    sphere = ps->sphere_shape_create();
    space = get_world_3d()->get_space();

    ps->shape_set_data(sphere, 0.5f);

    ps->body_set_space(test_body, space);
    ps->body_add_shape(test_body, sphere);
    ps->body_set_shape_transform(test_body, 0, Transform3D());
    ps->body_set_mode(test_body, PhysicsServer3D::BODY_MODE_RIGID_LINEAR);
    ps->body_set_param(test_body, PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, 1.0f);
    ps->body_set_param(test_body, PhysicsServer3D::BODY_PARAM_MASS, 10.0f);
    ps->body_set_collision_layer(test_body, 1);

    ps->body_set_state(test_body,PhysicsServer3D::BODY_STATE_CAN_SLEEP, false);

    Transform3D b_tr = get_global_transform().translated(Vector3(0.0f, 10.0f, 0.0f));
    ps->body_set_state(test_body, PhysicsServer3D::BODY_STATE_TRANSFORM, b_tr);
    ps->body_set_state(test_body, PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, Vector3(0.1f, 0.0f, 0.05f));
}

void PhysicsManager::_physics_process(double delta)
{
    if(running)
    {
        ps->body_add_constant_central_force(test_body, Vector3(0.0f, 0.25f, 0.0f));

        Transform3D body_transform = ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_TRANSFORM);
        UtilityFunctions::print(body_transform);
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_SLEEPING));
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY));
    }
}


void PhysicsManager::set_running(bool p_running)
{
    if(running == p_running)return;
    running = p_running;
}

bool PhysicsManager::is_running() const
{
    return running;
}

I registered them as in docs. Nothing espesial

This text will be hidden

1 Like

Not 100% sure why this is the fix so it was a bit of a demon to find, but try adding this to the top of your _physics_process function and let me know if things are as you wanted them to be.

	if (Engine::get_singleton()->is_editor_hint()) return; // Early return if we are in editor

So it will look like this (I added some things during testing that you won’t need but just want to give you the full picture):

void PhysicsManager::_physics_process(double delta)
{
	if (Engine::get_singleton()->is_editor_hint()) return; // Early return if we are in editor

    if(running)
    {
        ps->body_add_constant_central_force(test_body, Vector3(0.0f, 0.25f, 0.0f));
        Transform3D body_transform = ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_TRANSFORM);
        UtilityFunctions::print(body_transform);
        UtilityFunctions::print(ps->body_is_omitting_force_integration(test_body));
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_SLEEPING));
        UtilityFunctions::print(ps->body_get_state(test_body, PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY));
    }
}

Best of luck in your work!

1 Like

lol, it works, but… So i was tested it in editor only (well it just was simpler)
So I didn’t expect that PhysicsServer dosn’t work in editor 0_o.

May be I can use some property to enable it in editor? IDK =)

And also believe I know why there may be some problems with PhysicsServer. It changes positions in edition and in the game at the same time.

Here the log

log
Godot Engine v4.3.stable.arch_linux - https://godotengine.org
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
Vulkan 1.2.180 - Forward+ - Using Device #0: AMD - AMD Radeon RX 580 Series
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)

[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
_ready
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.004975, 9.975562, 0.002487)]
false
(0.0995, -0.48875, 0.04975)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.009925, 9.926872, 0.004963)]
false
(0.099003, -0.973806, 0.049501)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.014851, 9.854113, 0.007425)]
false
(0.098507, -1.455187, 0.049254)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.019751, 9.757467, 0.009876)]
false
(0.098015, -1.932911, 0.049007)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.024627, 9.637117, 0.012314)]
false
(0.097525, -2.406997, 0.048762)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.029479, 9.493244, 0.01474)]
false
(0.097037, -2.877462, 0.048519)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.034307, 9.326028, 0.017153)]
false
(0.096552, -3.344325, 0.048276)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.03911, 9.135648, 0.019555)]
false
(0.096069, -3.807603, 0.048035)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.04389, 8.922282, 0.021945)]
false
(0.095589, -4.267315, 0.047794)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.048645, 8.686109, 0.024323)]
false
(0.095111, -4.723478, 0.047556)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.053377, 8.427303, 0.026689)]
false
(0.094635, -5.176111, 0.047318)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.058085, 8.146042, 0.029043)]
false
(0.094162, -5.625231, 0.047081)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.06277, 7.842499, 0.031385)]
false
(0.093691, -6.070855, 0.046846)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.067431, 7.516849, 0.033716)]
false
(0.093223, -6.513, 0.046612)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.072069, 7.169265, 0.036034)]
false
(0.092757, -6.951685, 0.046378)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.076684, 6.799919, 0.038342)]
false
(0.092293, -7.386926, 0.046147)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.081275, 6.408981, 0.040638)]
false
(0.091832, -7.818742, 0.045916)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.085844, 5.996624, 0.042922)]
false
(0.091372, -8.247149, 0.045686)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.09039, 5.563016, 0.045195)]
false
(0.090916, -8.672162, 0.045458)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.094913, 5.108326, 0.047456)]
false
(0.090461, -9.093801, 0.045231)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.099413, 4.632722, 0.049707)]
false
(0.090009, -9.512082, 0.045004)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.103891, 4.136371, 0.051945)]
false
(0.089559, -9.927021, 0.044779)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 10, 0)]
false
(0.1, 0, 0.05)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.108346, 3.619439, 0.054173)]
false
(0.089111, -10.33864, 0.044555)
[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0.11278, 3.082092, 0.05639)]
false

Well. Thanks a lot for help! Will do a video soon. =)

1 Like

Oh, its not documented yet, as i understand.

This

And this function make it work in editor.

PhysicsServer3D::set_active(true)
1 Like

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