Godot-proposals: Allow RigidBody to have Colliders that are indirect children, not just direct children

Created on 15 Oct 2018  路  14Comments  路  Source: godotengine/godot-proposals

Describe the project you are working on:

I would like to create a voxel game where the objects' collisions are composed of many cube colliders. I can't use concave mesh colliders because I would like these voxel objects to be able to move.

Describe the problem or limitation you are having in your project:

The problem is that, while I can easily generate cube colliders, I have no good way to remove groups of them whenever I need to regenerate a "chunk".

Describe the feature / enhancement and how it helps to overcome the problem or limitation:

What I would like to do is have several of these cube colliders together as children of a child so that I can easily remove/generate/instance them as needed.

    Collider0
    ColliderGroupA
        Collider1
        Collider2
    ColliderGroupB
        Collider3
        Collider4

In the example above, in the current stable and master branch of Godot, only Collider0 is detected, and without it the RigidBody complains that it has no collider. It seems that colliders are only used if they are direct children.

Ideally, RigidBody should be able to use colliders that are grandchildren etc and not just direct children. This would make it easier for me to instance, generate, and delete groups of colliders. Basically, the RigidBody should recursively search its children for CollisionShape nodes, so that in the example above, it would use all of the colliders (0 through 4).

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

One issue that would arise from just recursively searching for collider children is that physics objects parented to physics objects would both use the child's colliders. There are many possible implementations that would solve this without that problem:

  • Configurable recursiveness/depth of colliders.

  • Don't look for colliders under other PhysicsBody nodes.

  • Only use direct children, but add a new "CompoundCollider" node which passes up its own children.

If this enhancement will not be used often, can it be worked around with a few lines of script?:

Possibly, but not nearly as clean. I really don't want to short-circuit the node hierarchy.

Is there a reason why this should be core and not an add-on in the asset library?:

This is a low-level feature that could not be implemented very well by an add-on.

See: https://godotengine.org/qa/31701/possible-rigidbody-have-colliders-that-not-direct-children

physics

Most helpful comment

I have complex maps that are StaticBody2Ds with lots of colliders and also children that are objects. Having an ability to group colliders to clean the mess would be very welcome.

CompoundCollider solution sounds nice.

All 14 comments

A problem I see here is that you may not always want this. Imagine your character is holding some item with its own Collider. If you shoot at the character, you don't want a hit on the item to count as a hit on the character.

How would Godot know which Colliders to consider?

@Hendrikto There are many possible solutions to this:

  • Configurable recursiveness/depth of colliders.

  • Don't look for colliders under certain node types (other PhysicsBody nodes would be obvious ones)

  • Only use direct children, but add a new "CompoundCollider" node which passes up its own children.

Note: Not the same as https://github.com/godotengine/godot/issues/7793, which proposes a feature called "Collision Groups" related to collision layers and masking, but my issue is about compounding colliders.

I have the same problem. I wanted to create damageable wall.

I have complex maps that are StaticBody2Ds with lots of colliders and also children that are objects. Having an ability to group colliders to clean the mess would be very welcome.

CompoundCollider solution sounds nice.

So I was going to make a proper proposal for this feature, but wanted to try one thing first and found a workaround for my use case.

extends Node2D

func _ready() -> void:
    for collider in get_children():
        call_deferred("move_collider", collider)

    queue_free()

func move_collider(collider: Node2D):
    remove_child(collider)
    get_parent().add_child(collider)

Just put your colliders under a node with above script and it will work perfectly. The only downside is warnings in the scene tree and probably a very slightly longer scene loading time.

@KoBeWi In my case I'd like to be able to delete groups of colliders at runtime. I would prefer to not have to store a separate data structure keeping track of what group each collider is a part of.

Consider that by default we are using compound under the hood, and I prefer to not add a node of this kind to allow recursive search.

A shape may have the possibility to find the physics body owner recursively, even when a physics body contains another one: The shape will stop its search soon it found its owner.

Physics body
|--Node
|    |- Shape
|
| -- PhysicsBody 2
|       |--Node
|            |- Shape

So, in current implementation a kinematicBody basically disables all collision shapes below, (indirect children) true? Is there a way we can enable them in code?

What I would like to do is have several of these cube colliders together as children of a child so that I can easily remove/generate/instance them as needed.

    Collider0
    ColliderGroupA
        Collider1
        Collider2
    ColliderGroupB
        Collider3
        Collider4

This is how a CollisionPolygon currently works. It is a CollisionObject that contains multiple shapes (whereas a CollisionShape is a CollisionObject that just holds one shape). Instead of the above layout, what you actually currently have is:

    Collider0
        Shape0
    Collider1
        Shape0
        Shape1
    Collider2
        Shape0
        Shape1

You can create your own using the CollisionObject API API. Create a shape_owner using create_shape_owner(), then add multiple shapes to it using shape_owner_add_shape().

In a recent project, one of the most common behaviors was adding a lot of shapes per single Physics Body; this was causing some performance issues, since the broad phase was not able to properly do its job.

Add 1 shape per Physics Body should be the way to go (unless you want to decompose a complex body shape to multiple convex shapes). This proposal would encourage put more shapes per body even more.

While initially I supported this feature, I think we should reconsider it, so to better guide the user.

@AndreaCatania so if best practice for performance is one shape and one CollisionObject, then when @aaronfranke wants to add a group of shapes (shapes from a group of new children) then iterate through the children and add each child's shape using shape_owner_add_shape with the owner_id created from each child?

Then, to remove a group of shapes (removing a group of children) use the shape_owner_remove_shape with each child's owner_id?

This would mean storing both the owner_id and shape_id (which I assume is the int returned by shape_owner_add_shape)?

Is that the process you would recommend?

Yes, thats sounds ok.
Bullet is really performant, though I doubt that its architecture allows you to achieve what you want.

A voxel game should have million little boxes, colliding each other, if thats the case You should consider optimizing at least its memory model (I can expand this more if you want) though other solutions may be more effective.

Thanks for the quick reply -- maybe not for Andrea but in my use case it may work out: I want a KinematicBody (doer) to grab another KinematicBody (victim) and start whirling it around, smashing it into things. If the victim is a child of doer, it's automatically transformed by doer's rotations which is what I want. The problem was that victim collisions weren't happening.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SpyrexDE picture SpyrexDE  路  3Comments

SleepProgger picture SleepProgger  路  3Comments

regakakobigman picture regakakobigman  路  3Comments

KoBeWi picture KoBeWi  路  3Comments

aaronfranke picture aaronfranke  路  3Comments