Collision Not Working Checklist

Collision Not Working Checklist

There’s a lot of ways that collision might not work as expected. Here are some reasons I’ve found. They are somewhat sorted in order of how likely I think they are to occur. None of these reasons are specific to 2D or 3D.

General Checklist

  1. You are running the wrong scene.
    • The Run Project (F5, the play button on the left of the other buttons) button only runs the main scene, which might not be the same thing as the scene you currently have open.
    • Run Current Scene (F6, the clapperboard icon with the play symbol on it) will run the current scene you have open.
    • The main scene can be changed in Project Settings or by right-clicking on the scene you want in the FileSystem.
  2. You didn’t add a collision shape.
    • All CollisionObjects need at least one CollisionShape or CollisionPolygon as a child in order to work with collision.
    • CollisionShapes need to have their shape property set in order to work with collision as well.
    • CollisionPolygons need to have a polygon drawn to work with collision as well.
    • The shape needs to be a direct child of the CollisionObject. There can’t be any other nodes in the hierarchy between them.
    • For TileSets, you need to add a physics layer in the Inspector and then draw the shapes in the paint tab in the TileSet docker. Make sure to click on each tile to set the shape.
  3. Your sprite isn’t in the same place as the collision shape.
    • Since the visuals are separate nodes from CollisionShapes/Polygons, they have separate positions and might be misaligned.
  4. Your CollsionShape/Polygon is disabled.
    • It will be gray in the editor if it’s disabled. You just need to turn disabled off on the CollisionShape/Polygon.
  5. You scaled the CollisionObject.
    • You should change the size of the CollisionShape/Polygon instead of changing the scale of any of the collision nodes.
  6. Your collision layers and masks are wrong.
    • A CollisionObject belongs to a collision_layer and a collision_mask is what the CollisionObject is looking for collisions with.
    • For example, if an Area2D has Mask 1 enabled and a CharacterBody2D with Layer 1 enters it, the Area2D will detect the CharacterBody2D.
    • If the CharacterBody2D’s layer 1 is disabled, and layer 2 is enabled, then the Area2D will no longer detect the CharacterBody2D, unless the Area2D’s mask 2 is also enabled.
  7. Your collision layers and masks are wrong in the scene you are testing.
    • If you instantiate a scene inside another with the editor, and then you modify a property on the instance, then that property is no longer in sync with the original scene’s property.
    • For example, if you change the collision layers on the instance first and then the original scene, the instance’s collision layers will not update to match the original scene.
    • You can click the reset icon next to the property to sync the property.
  8. The CollisionObjects are not in the same canvas.
    • Those kinds of collisions are not currently supported in Godot.
    • This includes CanvasLayer, ParallaxBackground, and Viewport.
  9. A fast moving object goes through another object it shouldn’t.
    • Tunneling might be fixed by enabling the continuous_cd property on RigidBodies.
    • Another way is to use a RayCast in front of the object to see if it will pass through another object the next physics frame.
  10. Changing one CollisionShape changes them all.
    • This is because those shapes are Resources, which are shared if you duplicated the node or copy/pasted the shape.
    • For nodes you are planning to instantiate with code, expand the Resource section in the shape and enable Local to Scene.
    • For nodes you have already instantiated in the editor, right-click on the shape and select Make Unique.
  11. You spelled a function name wrong.
    • It’s easy to forget the underscore (_) before _physics_process. It won’t be called automatically if you don’t type it.
  12. You didn’t call any movement functions.
    • For CharacterBodies, you need to call move_and_slide() or move_and_collide() after changing the velocity in order to move the character.
  13. You are multiplying by delta / not multiplying by delta.
    • delta is the variable passed into _physics_process() that is the time in seconds since the last frame. It’s most often less than 1.0 unless the game is running very slowly.
    • For CharacterBodies, velocity already takes time into account, so there is no need to multiply it by delta when changing it directly.
    • However, acceleration is change in velocity over time, so you will need to multiply acceleration by delta when modifying the velocity.
    • move_and_slide() takes no parameters, so multiplying by delta is not possible. But move_and_collide() expects a velocity multiplied by delta.
  14. You didn’t connect the signal.
    • Signals will not be automatically connected based on function names.
    • If you connect a signal via the editor, then when you have the script and the scene the signal was connected in open at the same time, a green “connected” icon will appear to the left of the line number of the function you connected the signal to. It might take a couple of seconds to show up. If it’s not there, then you need to connect the signal.
    • Alternately, you can connect signals through code. Make sure that the signal connects and doesn’t fail because the connecting object is null, and that you are connecting it to the right object.
  15. You disabled processing on the node.
    • Somewhere you have the line set_physics_process(false) (or the same for the _process function if you are using that instead).
  16. The node is paused.
    • If the SceneTree is paused and you haven’t changed any node’s process_mode, then all nodes will be paused, and there is no way to unpause the game.
    • Setting the process_mode to PROCESS_MODE_DISABLED will also pause the node. PROCESS_MODE_INHERIT will also pause the node if it has a parent that is paused.
  17. You are looking for the wrong kind of CollisionObject.
    • Make sure that if you’re using the on_body_entered signal, the node you’re looking for is actually a body (and the same for areas).
  18. Area is not set to monitoring.
    • It’s set to true by default, but you might have accidentally changed it.
  19. Camera is following a moving object.
    • If the player doesn’t appear to move and there are no other objects in the scene to compare it to, and the camera is a child of the player and is following it, the player might actually be moving, but you can’t see it. Add something to the background to compare the player to!
  20. There’s an error that tells you what’s wrong.
    • Check the debugger!
    • Errors are in red and warnings are in yellow. Errors are more severe than warnings, but you should check the warnings too, since one of those might tell you what the issue is.
  21. You found a bug.
    • You can report it on GitHub! Make sure to check if it’s been reported already, however.

Still Stuck?

If you couldn’t find the answer to your collision problem on this list, there are still steps you can take to debug your issue.

  1. Turn on debug collision shapes.
    • Under “Debug” in the top menu bar, enable “Visible Collision Shapes”. This will allow you to see them when you run the game.
  2. Print out variables / add breakpoints.
    • Use the print() function or click to the left of the line number to add a breakpoint (or type breakpoint). Breakpoints pause execution of the code, and allows you to advance step-by-step until you run into the error.
    • Seeing the actual values of the variables might give you insight into what’s wrong.
  3. Restart the engine.
    • Sometimes this works!
  4. Try to reproduce the issue on a new project.
    • While you are trying to recreate it, you could figure out what the issue is.

Conclusion

Collisions are complicated, so don’t feel bad for not getting them perfect the first time! :+1:

3 Likes