0
\$\begingroup\$

Using Godot 4.2.1, I have a 3D scene with a CharacterBody3D as the root. It has two children; a child CollisionShape3D, and a child CharacterBody3D with its own collision shape.

CharacterBody3D (scene root)
    CollisionShape3D (parent collision shape)
    CharacterBody3D (child)
        CollisionShape3D (child collision shape)

The scene root has a script which calls MoveAndSlide in PhysicsProcess(). It works fine for the parent and its collision shape, if you hit an obstacle, the parent stops moving. However I would like the parent to stop moving also if the child shape hits an obstacle, and that is not happening.

The child is not being moved manually through scripts, it's only being taken along with the parent's movement. I tried changing it to a StaticBody3D too, but the issue persists. The collision layers and masks are the same for both parent and child; if that was wrong, the collision wouldn't work for either.

How can I get the child's collision to be detected? And the movement to stop even when the child collides, same as the parent? Is there a solution that handles this issue even when the child is instantiated at runtime, through scripts?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I'm having a hard time visualizing what you mean.

From what I've seen in Godot, if movement is not controlled by the built in functions (like moveAndSlide()) collisions are not checked. So if the child is being dragged with the parent the child collisions likely aren't checked.

Something you can try to do is to use signals so that when the parent moves, a signal is fired. The signal would contain a vector indicating the movement expected of the child and then the child would respond to the signal by calling moveAndSlide() with the supplied vector.

I think the only challenge would be suppressing the child's native behavior of being dragged with the parent. The easy way to do this is not add it as a child to the parent but rather a sibling.

You can connect signals on dynamically instantiated objects. This is some c# code I use to do this but I believe this can also be done in GDScript:

PackedScene cellResource = ResourceLoader.Load<PackedScene>("res://TicTacToe/Scenes/GameBoard/Cell.tscn");
Godot.StringName signalName = new Godot.StringName("cellClicked");
Godot.Callable signalHandler = new Godot.Callable(this, MethodName.onCellClicked);
Cell cell = cellResource.Instantiate<Cell>();
cell.Connect(signalName, signalHandler);

Here's an answer on StackOverflow that I think does a great job at explaining collision: https://stackoverflow.com/questions/69728827/how-do-i-detect-collisions-in-godot

It does still emphasize the use of collision signals or the use of moveAndSlide/moveAndCollide functions.

\$\endgroup\$
8
  • \$\begingroup\$ "suppressing the child's native behavior of being dragged with the parent" - I want the child to be dragged by the parent. I'm trying to simulate the player picking up an item and carrying it in front of them. I'll try passing the movement vector with the signal \$\endgroup\$
    – devil0150
    Commented Jan 17 at 9:18
  • \$\begingroup\$ Calling moveAndCollide on the child with the parent vector didn't work - for every movement the parent makes, the child moves double that (once from the parent dragging it, and once from the script receiving the signal with the vector). Using moveAndCollide with a zero vector does work for the child object, but individually. It doesn't stop the whole movement (parent and child) when it collides, but instead displaces the child while the parent keeps moving. \$\endgroup\$
    – devil0150
    Commented Jan 17 at 17:42
  • \$\begingroup\$ You missed the part that I mentioned that you would have to suppress the child's natural behavior of being dragged along side the parent. Please re-read the answer. To stop both parent and child, you would have to react to the child sending a signal upon collision to prevent the parent from moving, you have to be careful as this may create a lock where neither the parent or child will move though. \$\endgroup\$
    – gNerb
    Commented Jan 18 at 16:47
  • \$\begingroup\$ Its also worth saying, that it sounds like my answer was correct in that in order for the child's collision to work, you must call move and slide. You should probably split this into multiple questions. \$\endgroup\$
    – gNerb
    Commented Jan 18 at 16:48
  • \$\begingroup\$ "I would like the parent to stop moving also if the child shape hits an obstacle" was in the question, that's what I am looking for. \$\endgroup\$
    – devil0150
    Commented Jan 18 at 16:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .