Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CollisionObject3D Gizmo not updated after changing collision with shape_owner_* functions in a @tool script #84540

Closed
Okxa opened this issue Nov 6, 2023 · 1 comment · Fixed by #84610

Comments

@Okxa
Copy link

Okxa commented Nov 6, 2023

Godot version

v4.1.2.stable.arch_linux

System information

Arch Linux

Issue description

When using shape_owner_* functions to add/remove collision shapes on a CollisionObject3D (and classes derived from it) in a tool mode script, the new shape is not visible in the editor until after deselecting & reselecting the node, or after the scene (tree) is reloaded. (Either by closing and reopening it, or by switching scene tabs.)

Most likely because the gizmo that handles showing this shape (CollisionObject3DGizmoPlugin) is not redrawn when the shape owners and their shapes change. The function responsible for drawing the shapes is:

void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_gizmo->get_node_3d());
p_gizmo->clear();
List<uint32_t> owner_ids;
co->get_shape_owners(&owner_ids);
for (uint32_t &owner_id : owner_ids) {
Transform3D xform = co->shape_owner_get_transform(owner_id);
Object *owner = co->shape_owner_get_owner(owner_id);
// Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo.
if (!Object::cast_to<CollisionShape3D>(owner) && !Object::cast_to<CollisionPolygon3D>(owner)) {
Ref<Material> material = get_material(!co->is_shape_owner_disabled(owner_id) ? "shape_material" : "shape_material_disabled", p_gizmo);
for (int shape_id = 0; shape_id < co->shape_owner_get_shape_count(owner_id); shape_id++) {
Ref<Shape3D> s = co->shape_owner_get_shape(owner_id, shape_id);
if (s.is_null()) {
continue;
}
SurfaceTool st;
st.append_from(s->get_debug_mesh(), 0, xform);
p_gizmo->add_mesh(st.commit(), material);
p_gizmo->add_collision_segments(s->get_debug_mesh_lines());
}
}
}
}

Steps to reproduce

  1. In a new scene, create a CollisionObject3D derived node (Like StaticBody3D) and attach the following script to it:
@tool
extends CollisionObject3D

var shape_owner:int
var shape
@export var collision:Shape3D:
    get:
        return shape
    set(value):
        shape = value
        if get_shape_owners().size() == 0: shape_owner = create_shape_owner(self)
        shape_owner_clear_shapes(shape_owner)
        if shape: shape_owner_add_shape(shape_owner, shape)
  1. Set the exported variable in the editor by adding a collision shape.
    • Notice how the visualization of the collision shape has not changed
  2. Deselect and reselect the node, or change scene tab between another scene and this scene, or save, close and reopen the scene
    • Notice that the new collision shape is now visible

Minimal reproduction project

collisionobject3d-gizmo-test.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants