KinematicBody2D with CollisionShape2D as a child scene -- collisions not working/detected

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By DashRantic

Hi,

I have a project where I am trying to create a player out of several difference scenes (with the player as a simple spaceship, with the main body of the ship as the main Player scene and two engines as separate sub-scenes). The issue is that the CollisionShape2D nodes on my sub-scenes do not seem to function – only the CollisionShape2D on the main Player scene is interacting with walls created via a TileMap correctly. The PhysicsBody2D Collision Mask layer settings seem to be correct, with the mask for the Player scene and sub-scenes set to be the same.

The CollisionBody2D on the root Player scene is working correctly, it is just the CollisionBody2Ds from the sub-scenes that do not appear to be engaging with the walls. The layout for my Player scene is as follows:

KinematicBody2D (root node / Player scene)
 - Sprite
 - CollisionShape2D
 - ShipEngine_left
 - ShipEngine_right

The “ShipEngine_left” and “ShipEngine_right” nodes are instances of another scene, “ShipEngine”. The node hierarchy for this scene is:

KinematicBody2D (root node for the engine scene)
 - Sprite (engine sprite)
 - CollisionShape2D
 - AnimatedSprite (displays the "flames" when engaging the engine)

All of this is working (ship flying correctly, engines animated correctly, entire ship rotating together correctly, etc) except for the CollisionShape2Ds on the ShipEngine sub-nodes. The CollisionShape2D on the main ship body/Player scene is detecting and handling basic collisions with walls correctly, but the engines are passing right through walls and the entire ship does not stop/bounce off until the main body’s CollisionShape2D hits the walls. Is there any way I can keep the CollisionShape2Ds on the child scenes, instead of adding those CollisionShape2Ds to the root Player scene? Or does Godot require that all collision shapes be in the Player’s root node?

In my searching for an answer, the closest thing I found was the following issue on github, which is now marked as closed…

Any advice would be greatly appreciated!

Godot version: 3.2.1.stable.official
Game type: 2D
Render engine: GLES3
Development platform: macOS (High Sierra)

Very wild guess:

Maybe you need joints to connect the bodies together.

whiteshampoo | 2020-06-25 09:15

Joints don’t appear to work with KinematicBody2D.

DashRantic | 2020-06-25 16:01

can you provide your project-folder?

whiteshampoo | 2020-06-25 16:03

:bust_in_silhouette: Reply From: Jorge

Have you check the layers and mask ?

:bust_in_silhouette: Reply From: brainbug

the child Bodys are not moved with move_and_slide() or
move_and_collide.
Therefore no collision.
Add the CollisionShape2D to the Player.

You can copy them in your Player script.

func _ready():
for child in get_children():
	if child is KinematicBody2D:
		var id: = self.create_shape_owner(self)
		var shape:Shape2D = child.shape_owner_get_shape(0,0).duplicate()
		self.shape_owner_add_shape(id,shape)
		self.shape_owner_set_transform(id,child.transform)	

Thanks, I ended up doing this and is seems to be working :slight_smile:

DashRantic | 2020-06-30 05:28