Physics body doesn't move(in PhysicsServer3D)

Godot Version

4.2.2

Question

I actived the space, added body to the space but it still doesn’t move.
Both entity and body the preset added doesn’t work.
Sorry for a lot of code.

My code:

preset/test.gd

extends Preset

static var logger = Log.register_logger("*_Preset_Test_LogSource")

class Tracker extends Node:
    var phyrid: RID

    func _physics_process(_delta: float) -> void:
        print(PhysicsServer3D.body_get_state(phyrid, PhysicsServer3D.BODY_STATE_TRANSFORM))

var directional_light: RID
var instance: RID
var instance2: RID

var body: RID
var shape: RID

var mesh = BoxMesh.new()

func _data() -> void:
    super._data()
    id = "test"

func _assign() -> void:
    Vars.presets.register_preset_group("*").add(self)

func _show_description(node: ScrollContainer) -> void:
    var label = Label.new()
    label.text = tr("*_Presets_Test_Description")
    node.add_child(label)

func _pre_config_preset() -> bool:
    return true

func _init_preset() -> void:
    var world = Vars.worlds.create_world()
    var entity = TestEntity.TYPE.create(false)
    world.add_child_entity(entity)
    entity.object_create()

    entity = Hidden_Entity_Test.TYPE.create(false)
    entity.transform = Transform3D(Basis.IDENTITY, Vector3(0, 8, 0))

    world.add_child_entity(entity)
    entity.object_create()

func _after_ready() -> void:
    directional_light = RenderingServer.directional_light_create()
    RenderingServer.light_set_color(directional_light, Color.WHITE)
    RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_ENERGY, 1)
    RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_INDIRECT_ENERGY, 1)
    RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_RANGE, 100)

    instance = RenderingServer.instance_create()
    RenderingServer.instance_set_base(instance, directional_light)
    RenderingServer.instance_set_transform(instance, Transform3D.IDENTITY.rotated(Vector3.RIGHT, -PI / 6).rotated(Vector3.UP, PI / 6))
    RenderingServer.instance_set_scenario(instance, Vars.worlds.worlds[1].scenario)

    # mesh.size = Vector3(100, 2, 100)

    PhysicsServer3D.area_set_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY, 9.8)
    PhysicsServer3D.area_set_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR, Vector3.DOWN)
    logger.debug("Setup gravity: %s for %s" % [PhysicsServer3D.area_get_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY), Vars.worlds.worlds[1].space])

    shape = PhysicsServer3D.box_shape_create()
    PhysicsServer3D.shape_set_data(shape, Vector3(1, 1, 1))
    logger.debug("Created shape: %s" % str(shape))

    body = PhysicsServer3D.body_create()
    PhysicsServer3D.body_add_shape(body, shape, Transform3D.IDENTITY, 1)
    PhysicsServer3D.body_set_state(body, PhysicsServer3D.BODY_STATE_TRANSFORM, Transform3D.IDENTITY.translated(Vector3(0, -5, 0)))
    PhysicsServer3D.body_set_mode(body, PhysicsServer3D.BODY_MODE_RIGID)
    logger.debug("Created body: %s" % str(body))
    PhysicsServer3D.body_set_space(body, Vars.worlds.worlds[1].space)
    logger.debug("Attached body: %s to space: %s" % [body, Vars.worlds.worlds[1].space])

    print(PhysicsServer3D.space_is_active(Vars.worlds.worlds[1].space))

    var tracker = Tracker.new()
    tracker.phyrid = body
    Vars.add_child(tracker)

    Vars.worlds.worlds[1].toggle_to.call_deferred()

    # instance2 = RenderingServer.instance_create()
    # RenderingServer.instance_set_base(instance2, mesh.get_rid())
    # RenderingServer.instance_set_transform(instance, Transform3D.IDENTITY \
    #         .translated(Vector3.DOWN * 0.2))
    # RenderingServer.instance_set_scenario(instance2, Vars.worlds.worlds[1].scenario)

func _apply_preset() -> void:
    pass

func _enable_preset() -> void:
    pass

func _disable_preset() -> void:
    RenderingServer.free_rid(directional_light)
    RenderingServer.free_rid(instance)
    RenderingServer.free_rid(instance2)

func _load_preset_data(_stream: Stream) -> Error:
    return OK

func _save_preset_data(_stream: Stream) -> void:
    pass

entities/test.gd

class_name Hidden_Entity_Test
extends StandalonePhysicsEntity

static func get_type() -> ObjectType:
    return (Gindustry_Entity_Test as Object).get_meta(OBJECT_TYPE_META)

var shape_rid: RID
var shape: int

var box: BoxMesh
var instance: RID

func _object_init() -> void:
    super._object_init()
    shape_rid = PhysicsServer3D.box_shape_create()
    PhysicsServer3D.shape_set_data(shape_rid, Vector3(1, 1, 1))
    
    shape = add_shape(shape_rid, Transform3D.IDENTITY, 1)

    box = BoxMesh.new()
    box.size = Vector3(1, 1, 1)
    box.material = StandardMaterial3D.new()

    box.material.albedo_color = Color(1, 0, 0)
    instance = RenderingServer.instance_create()
    RenderingServer.instance_set_base(instance, box.get_rid())

    PhysicsServer3D.body_set_mode(physics_body_rid, PhysicsServer3D.BODY_MODE_RIGID)

func _object_free() -> void:
    PhysicsServer3D.free_rid(shape_rid)
    RenderingServer.free_rid(instance)

    super._object_free()

func _entity_init() -> void:
    super._entity_init()

    RenderingServer.instance_set_scenario(instance, world.scenario)

func _entity_deinit() -> void:
    super._entity_deinit()

func _load_data(stream: Stream) -> Error:
    var err = super._load_data(stream)
    if err: return err
    return Utils.load_data_with_version(stream, [])

func _save_data(stream: Stream) -> void:
    super._save_data(stream)
    Utils.save_data_with_version(stream, [])

func _on_transform_changed(source: Entity) -> void:
    super._on_transform_changed(source)

    RenderingServer.instance_set_transform(instance, get_global_transform())


world.gd

class_name World
extends Entity

static var logger: Log.Logger

const TILE_SIZE = 0.25
const TILE_SIZE_VECTOR = Vector3.ONE * TILE_SIZE

static func get_type() -> ObjectType:
    return (World as Object).get_meta(OBJECT_TYPE_META)

var is_root_world: bool = false;

var scenario: RID:
    get: return parent_entity.scenario if parent_entity and parent_entity != self else scenario
    set(v): scenario = v;
var space: RID:
    get: return parent_entity.space if parent_entity and parent_entity != self else space
    set(v): space = v;
var camera: RID:
    get: return parent_entity.camera if parent_entity and parent_entity != self else camera
    set(v): camera = v

var chunks: Dictionary = {} # Vector3i -> Chunk

static func create() -> World:
    return TYPE.create();

func _object_create() -> void:
    super._object_create()
    if not logger:
        logger = Log.register_logger("World_LogSource")

func _object_init() -> void:
    super._object_init()
    Vars.worlds.worlds[object_id] = self 
    if is_root_world:
        self.world = self
        scenario = RenderingServer.scenario_create()
        logger.debug("Scenario created: %s" % str(scenario))

        space = PhysicsServer3D.space_create()
        logger.debug("Space created: %s" % str(space))

        camera = RenderingServer.camera_create()
        RenderingServer.camera_set_cull_mask(camera, 1)
        RenderingServer.camera_set_transform(camera, Transform3D.IDENTITY)

func _object_ready() -> void:
    if object_ready: return
    super._object_ready()

    if is_root_world:
        PhysicsServer3D.space_set_active(space, true)
        logger.debug("Space active: %s" % str(space))

func _object_free() -> void:
    if is_root_world:
        if Vars.worlds.current_toggled_world == self:
            RenderingServer.viewport_set_scenario(get_viewport().get_viewport_rid(), RID())
            RenderingServer.viewport_attach_camera(get_viewport().get_viewport_rid(), RID())
            Vars.worlds.current_toggled_world = null
        PhysicsServer3D.free_rid(space)

        RenderingServer.free_rid(camera)
        RenderingServer.free_rid(scenario)
    super._object_free()

func toggle_to() -> void:
    if not object_ready: return

    if Vars.worlds.current_toggled_world == root_world: return
    Vars.worlds.current_toggled_world = root_world

    var viewport = get_viewport()
    RenderingServer.viewport_set_scenario(viewport.get_viewport_rid(), root_world.scenario)
    RenderingServer.viewport_attach_camera(viewport.get_viewport_rid(), root_world.camera)

func _load_data(stream: Stream) -> Error:
    super._load_data(stream)
    return Utils.load_data_with_version(stream, [func():
        is_root_world = stream.get_8() == 1;
        if stream.get_error(): return stream.get_error()
        return OK
    ])

func _save_data(stream: Stream) -> void:
    super._save_data(stream)
    Utils.save_data_with_version(stream, [func():
        stream.store_8(1 if is_root_world else 0);
    ])

physics_entity.gd

class_name PhysicsEntity
extends Entity

signal shape_data_changed(shapeidx: int)

static func get_type() -> ObjectType:
    return (PhysicsEntity as Object).get_meta(OBJECT_TYPE_META)

func _get_physics_body_rid() -> RID:
    return RID()

func get_physics_body_rid() -> RID:
    return _get_physics_body_rid()

func get_parent_standalone_physics_entity() -> StandalonePhysicsEntity:
    var curr = self
    while curr:
        if curr is StandalonePhysicsEntity:
            return curr
        curr = curr.parent_entity
    return null

var shape_inc_idx: int = 1
var shapes: Dictionary = {}
var shape_transforms: Dictionary = {}
var shape_attached_idxs: Dictionary = {}
var shape_masses: Dictionary = {}

func __attach_shape(shapeidx: int) -> void:
    PhysicsServer3D.body_add_shape(get_physics_body_rid(), \
        shapes[shapeidx], Transform3D.IDENTITY)
    shape_attached_idxs[shapeidx] = PhysicsServer3D.body_get_shape_count(get_physics_body_rid()) - 1
    __update_shape(shapeidx)

func __update_shape(shapeidx: int) -> void:
    var parent = get_parent_standalone_physics_entity()
    var shape_local = get_relative_transform(parent).affine_inverse() * shape_transforms[shapeidx]
    PhysicsServer3D.body_set_shape_transform(get_physics_body_rid(), \
        shape_attached_idxs[shapeidx], shape_local)
    shape_data_changed.emit(shapeidx)
    parent.physics_child_shape_changed(self)

func __detach_shape(shapeidx: int) -> void:
    PhysicsServer3D.body_remove_shape(get_physics_body_rid(), shape_attached_idxs[shapeidx])
    var idx = shape_attached_idxs[shapeidx]
    shape_attached_idxs.erase(shapeidx)
    for sidx in shape_attached_idxs:
        if shape_attached_idxs[sidx] > idx:
            shape_attached_idxs[sidx] -= 1

func add_shape(shape: RID, shape_transform: Transform3D, mass: float = 0) -> int:
    var idx = shape_inc_idx
    shapes[idx] = shape
    shape_transforms[idx] = shape_transform
    shape_masses[idx] = mass
    if entity_active:
        __attach_shape(idx)
    shape_inc_idx += 1
    return idx

func set_shape_transform(shapeidx: int, shape_transform: Transform3D) -> void:
    shape_transforms[shapeidx] = shape_transform
    if entity_active and shape_attached_idxs.has(shapeidx):
        __update_shape(shapeidx)

func set_shape_mass(shapeidx: int, mass: float) -> void:
    shape_masses[shapeidx] = mass
    if entity_active and shape_attached_idxs.has(shapeidx):
        __update_shape(shapeidx)

func remove_shape(shapeidx: int) -> void:
    if not shapes.has(shapeidx): return
    if entity_active:
        __detach_shape(shapeidx)
    shapes.erase(shapeidx)
    shape_transforms.erase(shapeidx)
    shape_attached_idxs.erase(shapeidx)

func has_shape(shapeidx: int) -> bool:
    return shapes.has(shapeidx)

func _entity_init() -> void:
    super._entity_init()
    for shapeidx in shapes:
        __attach_shape(shapeidx)

func _entity_deinit() -> void:
    for shapeidx in shapes:
        __detach_shape(shapeidx)
    super._entity_deinit()

standalone_physics_entity.gd

class_name StandalonePhysicsEntity
extends PhysicsEntity

static var logger = Log.register_logger("StandalonePhysicsEntity_LogSource")

static func get_type() -> ObjectType:
    return (StandalonePhysicsEntity as Object).get_meta(OBJECT_TYPE_META)

var physics_body_rid: RID
var physics_child_entities: Array[PartialPhysicsEntity]
var in_physics_transform_sync: bool = false

var physics_last_transform: Transform3D

func _object_init() -> void:
    super._object_init()
    physics_body_rid = PhysicsServer3D.body_create()
    PhysicsServer3D.body_attach_object_instance_id(physics_body_rid, get_instance_id())

func _get_physics_body_rid() -> RID:
    return physics_body_rid

func _object_free() -> void:
    if physics_body_rid:
        PhysicsServer3D.free_rid(physics_body_rid)
        physics_body_rid = RID()
    super._object_free()

func _entity_init() -> void:
    super._entity_init()
    __update_physics()
    PhysicsServer3D.body_set_space(physics_body_rid, world.space)
    logger.debug("Set space: %s for %s" % [world.space, physics_body_rid])

    PhysicsServer3D.body_apply_force(physics_body_rid, Vector3.UP * 100, Vector3.ZERO)

func _entity_deinit() -> void:
    PhysicsServer3D.body_set_space(physics_body_rid, RID())
    logger.debug("Unset space: %s" % str(physics_body_rid))
    super._entity_deinit()

func _physics_process(_delta: float) -> void:
    if not entity_active: return
    var rid = get_physics_body_rid()
    if not rid.is_valid(): return
    var new_transform = PhysicsServer3D.body_get_state(rid, PhysicsServer3D.BODY_STATE_TRANSFORM)
    physics_transform_changed(new_transform)

func physics_transform_changed(new_transform: Transform3D) -> void:
    if physics_last_transform.is_equal_approx(new_transform): return
    physics_last_transform = new_transform
    in_physics_transform_sync = true
    new_transform = parent_entity.get_global_transform().affine_inverse() * new_transform
    transform = new_transform
    in_physics_transform_sync = false

func _on_transform_changed(source: Entity) -> void:
    super._on_transform_changed(source)
    if in_physics_transform_sync: return
    if source is StandalonePhysicsEntity and source != self:
        var rid = get_physics_body_rid()
        var new_transform = PhysicsServer3D.body_get_state(rid, PhysicsServer3D.BODY_STATE_TRANSFORM)
        physics_transform_changed(new_transform)
        return
    var global_transform = get_global_transform()
    PhysicsServer3D.body_set_state(physics_body_rid, PhysicsServer3D.BODY_STATE_TRANSFORM, \
            global_transform)
    physics_last_transform = global_transform

func add_physics_child(child: PartialPhysicsEntity) -> void:
    physics_child_entities.append(child)
    if entity_active: __update_physics()

func remove_physics_child(child: PartialPhysicsEntity) -> void:
    physics_child_entities.erase(child)
    if entity_active: __update_physics()

func physics_child_shape_changed(_child: PhysicsEntity) -> void:
    __update_physics()

func __update_physics() -> void:
    var centroid_sum = Vector3()
    var mass = 0
    for shapeidx in shape_attached_idxs:
        var origin = shape_transforms[shapeidx].origin
        origin = get_relative_transform(self).affine_inverse() * origin
        var shape_mass = shape_masses[shapeidx]
        centroid_sum += origin * shape_mass
        mass += shape_mass
    for child in physics_child_entities:
        for shapeidx in child.shape_attached_idxs:
            var origin = child.shape_transforms[shapeidx].origin
            origin = child.get_relative_transform(self).affine_inverse() * origin
            var shape_mass = child.shape_masses[shapeidx]
            centroid_sum += origin * shape_mass
            mass += shape_mass
    PhysicsServer3D.body_set_param(physics_body_rid, PhysicsServer3D.BODY_PARAM_CENTER_OF_MASS, \
            centroid_sum / mass)
    PhysicsServer3D.body_set_param(physics_body_rid, PhysicsServer3D.BODY_PARAM_MASS, mass)

Output:

...
[Main_LogSource]	[LogLevel_Info]	Main_StateChanged Core_State_MAIN_MENU Core_State_PRESET_CONFIG
[Game_LogSource]	[LogLevel_Info]	Game_LoadStarted
[Main_LogSource]	[LogLevel_Info]	Main_StateChanged Core_State_PRESET_CONFIG Core_State_LOADING_GAME
[World_LogSource]	[LogLevel_Debug]	Scenario created: RID(10548439678977)
[World_LogSource]	[LogLevel_Debug]	Space created: RID(10638633992192)
[Game_LogSource]	[LogLevel_Info]	Game_Ready
[World_LogSource]	[LogLevel_Debug]	Space active: RID(10638633992192)
[StandalonePhysicsEntity_LogSource]	[LogLevel_Debug]	Set space: RID(10638633992192) for RID(10758893076481)
[Game_LogSource]	[LogLevel_Info]	Game_Enter
[Main_LogSource]	[LogLevel_Info]	Main_StateChanged Core_State_LOADING_GAME Core_State_IN_GAME
[*_Preset_Test_LogSource]	[LogLevel_Debug]	Setup gravity: 9.80000019073486 for RID(10638633992192)
[*_Preset_Test_LogSource]	[LogLevel_Debug]	Created shape: RID(11265699217409)
[*_Preset_Test_LogSource]	[LogLevel_Debug]	Created body: RID(11338713661442)
[*_Preset_Test_LogSource]	[LogLevel_Debug]	Attached body: RID(11338713661442) to space: RID(10638633992192)
true
(268) [X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, -5, 0)]

Solved.

I checked my code and found get_tree().paused = true lol.

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