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

Allow RigidBody to have Colliders that are indirect children, not just direct children #535

Open
aaronfranke opened this issue Oct 15, 2018 · 21 comments · May be fixed by godotengine/godot#77937

Comments

@aaronfranke
Copy link
Member

aaronfranke commented Oct 15, 2018

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.

RigidBody
    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.

EDIT: Actually, the way Godot implements these nodes is that CollisionShape3D looks up the tree, so there is no problem. We can simply have the CollisionShape3D search up until it finds a CollisionObject3D node, then stop.

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

Bugsquad edit (keywords for easier searching): subchildren, subchild

@aaronfranke aaronfranke changed the title Allow RigidBody to have nested Colliders, not just direct children Allow RigidBody to have Colliders that are indirect children, not just direct children Oct 15, 2018
@Hendrikto
Copy link

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?

@aaronfranke
Copy link
Member Author

aaronfranke commented Oct 16, 2018

@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.

EDIT: Actually, the way Godot implements these nodes is that CollisionShape3D looks up the tree, so there is no problem. We can simply have the CollisionShape3D search up until it finds a CollisionObject3D node, then stop.

@aaronfranke
Copy link
Member Author

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

@ripperdave
Copy link

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

@KoBeWi
Copy link
Member

KoBeWi commented Sep 15, 2019

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.

@KoBeWi
Copy link
Member

KoBeWi commented Sep 16, 2019

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.

@aaronfranke
Copy link
Member Author

@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.

@AndreaCatania
Copy link

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

@jcarlosrc
Copy link

jcarlosrc commented Jun 12, 2020

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?

@madmiraal
Copy link

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.

RigidBody
    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:

RigidBody
    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().

@AndreaCatania
Copy link

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.

@KevinTriplett
Copy link

KevinTriplett commented Nov 15, 2020

@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?

@AndreaCatania
Copy link

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.

@KevinTriplett
Copy link

KevinTriplett commented Nov 15, 2020

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.

@memphis88
Copy link

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().

Thanks @madmiraal, that helped my use case which I couldn't find a solution for and I have a feeling it is somewhat common (I'm mostly referring to the limitation of shapes requiring to be direct children of PhysicsBody). To elaborate, I wanted to have my collision shape attached to a bone so that it follows the animation of my player in jumps etc, (see screenshot).
image

@Wokarol
Copy link

Wokarol commented Nov 8, 2022

While creating my own issue, I failed to search for this one. Sorry for that.

Is there any information as of recently about possibility of this feature being added as that really is a problematic limitation for any complex character or actor?

@Shadowblitz16
Copy link

Can we get this for CollisionObject2D and CollisionObject3D? instead of RigidyBodys?

@aaronfranke
Copy link
Member Author

@Shadowblitz16 Yes. That's what the PR I made does: godotengine/godot#77937

@ctrlraul
Copy link

I have an use case where the amount of shapes is dynamic, they also need to be re-ordered, added, removed... Having a node to group for them would be extremely helpful as to not conflict with the other nodes in the rigid body (Like sprite, etc...)

@StoqnS14

This comment was marked as off-topic.

@TheMaydayMan
Copy link

This would be so very convenient in my polygons project where it's easier to have
RigidBody2D
|-- Polygon2D
|-- CollisionPolygon2D

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.