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

Physic Body Instanced scene doesn't use CollisionShapes #2314

Closed
FEDE0D opened this issue Jul 28, 2015 · 17 comments
Closed

Physic Body Instanced scene doesn't use CollisionShapes #2314

FEDE0D opened this issue Jul 28, 2015 · 17 comments

Comments

@FEDE0D
Copy link
Contributor

FEDE0D commented Jul 28, 2015

When instancing a PhysicBody2D node (don't know if this is true for 3d as well) the new CollisionShape or CollisionPolygon nodes added as childs of the instanced scene are not used for the collisions.

This is the hierachy:

main_node
    - other nodes
    - instanced RigidBody2D
        - ... (other child nodes saved inside RigidBody2D)
        - CollisionShape2D (new node added to the instanced scene, does not work)

I think this is useful in a lot of ways, but it also follows the whole idea of "instanced scenes". Besides if it works with other nodes, why not with collision shapes?

Here's a test project: https://dl.dropboxusercontent.com/u/274954519/instance_scene_collision_test.zip

@slapin
Copy link
Contributor

slapin commented Jul 30, 2015

This problem is due to how godot handles collision shapes.
CollisionShape is just helper node which does add_shape your shapes (resources you create in
CollisionShape) and CollisionShape doesn't exist during runtime.
The problem is that CollisionShape node will add shapes to their ascender on the current scene tree,
and if none, they will be just removed.
To make this work, just add your shapes by hand to the collision body.
Or setup collision body and CollisionShapes children of it in the same scene.

@FEDE0D
Copy link
Contributor Author

FEDE0D commented Jul 30, 2015

That still doesn't solve the issue. The collision shape should be process and added to the parent.

@kubecz3k
Copy link
Contributor

kubecz3k commented Aug 3, 2015

In 2.0 Alpha there is quite elegant and simple workaround, a script that we can be added to collision shape:

extends CollisionShape
func _ready():
    get_parent().add_shape(get_shape());

@leonkrause
Copy link
Contributor

This issue persists with new instancing system (422929e).

@vnen vnen changed the title [BUG] Physic Body Instanced scene doesn't use CollisionShapes Physic Body Instanced scene doesn't use CollisionShapes Oct 31, 2015
@reduz reduz added this to the 3.0 milestone Jan 2, 2016
@reduz
Copy link
Member

reduz commented Jan 2, 2016

will not be fixed until 3.0 because it needs compatibility breakage for it to be made to work properly :(

@kubecz3k
Copy link
Contributor

kubecz3k commented Jan 2, 2016

@reduz can't it be fixed just by adding check in "ready" equivalent of c++ core code of CollisionSphere?
CollisionSphere could automatically check if it's registered in parent and if not then add self to the parent.
In GD script it would be something like (pseudocode written from head):

func ready():
   var need2RegisterInParent = isShapeInParent(self);
   if(need2RegisterInParent):
      get_parent().add_shape(get_shape());

func isShapeInParent(inShape2Check):
   var parentShapeCount = get_parent().get_count();
   for idx in range(parentShapeCount):
      var currentShape = get_parent().get_shape(idx);
      if(currentShape==inShape2Check):
         return true;
   return false;

@leonkrause
Copy link
Contributor

As noted in #4348, this concerns all CollisionObjects, not just PhysicsBodies

@bojidar-bg
Copy link
Contributor

Ahah, finally was able to workaround this in a game of mine:

extends CollisionObject2D

func _ready():
    for shape in get_children():
        if shape.has_meta("__registered") and shape.get_meta("__registered"):
            continue

        get_tree().set_editor_hint(true)

        remove_child(shape) # Make it pick up the editor hint
        add_child(shape)

        get_tree().set_editor_hint(false) # Unset quickly

        if shape extends CollisionShape2D: # Now update parent is working, so just change the shape
            shape.set_shape(shape.get_shape())
        elif shape extends CollisionPolygon2D:
            shape.set_polygon(shape.get_polygon())

        remove_child(shape) # Reset its editor hint cache, just in case it was needed.. (you might drop this part if it bottlenecks)
        add_child(shape)

        shape.set_meta("__registered", true)

@slapin
Copy link
Contributor

slapin commented Nov 19, 2016

Well, this is really heavy hack I'd say... I think it is better to patch
engine than do this...

On Sat, Nov 19, 2016 at 6:12 PM, Bojidar Marinov notifications@github.com
wrote:

Ahah, finally was able to workaround this in a game of mine:

extends CollisionObject2D
func _ready():
for shape in get_children():
if shape.has_meta("__registered") and shape.get_meta("__registered"):
continue

    get_tree().set_editor_hint(true)

    remove_child(shape) # Make it pick up the editor hint
    add_child(shape)

    get_tree().set_editor_hint(false) # Unset quickly

    if shape extends CollisionShape2D: # Now update parent is working, so just change the shape
        shape.set_shape(shape.get_shape())
    elif shape extends CollisionPolygon2D:
        shape.set_polygon(shape.get_polygon())

    remove_child(shape) # Reset its editor hint cache, just in case it was needed.. (you might drop this part if it bottlenecks)
    add_child(shape)

    shape.set_meta("__registered", true)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#2314 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAX0ysLkBxkFXhyphLFqA3ZL2BlueM6ks5q_xHfgaJpZM4Fhh8N
.

@bojidar-bg
Copy link
Contributor

@slapin You think its heavy? No, it's relatively lightweight, but it would all be better if there aren't hacks for this.

@bkeys
Copy link
Contributor

bkeys commented Dec 29, 2016

I would like to report that this is also happening with vehicle wheels so this is likely an issue for more than just collision shapes

@radishes
Copy link
Contributor

radishes commented Mar 5, 2017

I believe I am encountering this with an instanced Area2D, where the Area2D is defined in a parent scene, and the CollisionShape2D is defined in a scene which derives from the parent scene. I've created a sample project that reproduces the issue.
Area2D-instance-bug.zip
I'm not certain this is the same issue, but it looks like it is, so I will refrain from filing a new bug unless requested to do so. Thanks!

I'm using Godot 2.1.

I also believe this is the cause of https://godotengine.org/qa/3156/collision-callbacks-dont-fire-on-embedded-area2d-class.

@xphere
Copy link

xphere commented Apr 12, 2017

Just got bitten by this bug too, thanks @bojidar-bg for the workaround, though it only works for a single shape. When multiple shapes are defined, only the first is detected. Any idea why?

@bojidar-bg
Copy link
Contributor

@xphere Sounds strange, though you should probably try to tweak the workaround yourself -- AFAIR it might not always work with CollisionShape2D nodes (unlike CollisionPolygon2D nodes)

@xphere
Copy link

xphere commented Apr 13, 2017

Thanks, @bojidar-bg

For some reason, when dealing with multiple shapes, the workaround fails to add the last one.
Moving the calls to set_editor_hint out of the loop fixes this.
I've created a test project to test this, code can be found here.

I hope this will be fixed in core so we don't need ugly workarounds.

@kubecz3k
Copy link
Contributor

kubecz3k commented Aug 2, 2017

I think this should be fixed now. Can you recheck?

@reduz
Copy link
Member

reduz commented Aug 4, 2017

this is definitely fixed now, so closing

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

No branches or pull requests

10 participants