I’m creating a 2D chain reaction game. I have two-pronged “sprockets” laid out in a grid, and when one is clicked, it should rotate 90 degrees, and if it collides with another sprocket, then that sprocket should rotate, collide with others, and so on. The problem is, when a sprocket rotates, there is no collision detection, even though their CollisionShape2Ds end up overlapping.
The sprockets are all duplicates of a scene and set up as:
RigidBody2D
– Sprite2D
– CollisionShape2D
The RigidBody2D has both layer and mask set to “1”.
I have an “_on_body_entered” signal connected to the “_on_body_entered” function.
Here is my code. Any help would be greatly appreciated. And if you need more info from me, just let me know.
Thanks.
extends RigidBody2D
var target_rotation: float = 0
var rotation_increment: float = 90
var lerp_speed: float = 5
var is_rotating: bool = false
@onready var sprite = $Image
func _ready():
set_process_input(true)
func _process(delta):
if is_rotating:
rotation_degrees = lerp(rotation_degrees, target_rotation, lerp_speed * delta)
if abs(rotation_degrees - target_rotation) < 0.1:
rotation_degrees = target_rotation
is_rotating = false
func _input(event):
if event is InputEventMouseButton and event.pressed:
if event.button_index == MOUSE_BUTTON_LEFT:
var local_mouse_position = sprite.to_local(event.position)
var bounding_box = Rect2(Vector2(), sprite.texture.get_size())
if bounding_box.has_point(local_mouse_position):
target_rotation += rotation_increment
is_rotating = true
func _on_body_entered(body):
if body is RigidBody2D and body != self:
print("Collision detected with another sprocket")
var other_sprocket = body as RigidBody2D
other_sprocket.propagate_rotation(rotation_increment)
func propagate_rotation(rot_value: float):
var new_target_rotation = rotation_degrees + rot_value
if new_target_rotation >= 360:
new_target_rotation -= 360
target_rotation = new_target_rotation
is_rotating = true
If all bodies are Layer 1, Mask 1, they should should collide but not overlap, as they are colliding with each other’s company boundaries, same way a player body landing on a platform would not overlap the platform’s collision box. You said they do overlap, but I still think the problem lies in that collision setup.
There are a few things that can cause problems there.
First, just covering the basics.
Check if you are getting the _on_body_entered callback called. A very common mistake is not increasing the “Max contact points” from 0, and activating “Contact Monitor” inside the Solver zone of the rigidbody2D.
Without this, there will be no body_entered signals emitted.
Second:
This can cause a LOT of problems. Specially when dealing with rigidbodies.
Always prefer to use _physics_process to move/rotate things when possible.
But the real problem is that you are changing the rotation of the rigidbody.
Doing so will break the physics.
Always move rigidbodies with apply_force and apply_torque inside process functions, or else you’ll be overriding the physics and make a chain of things break.
If you must manually change the rotation or position, then you must do so inside a special function named “_integrate_forces”, within the state variable.
Not sure if that is your specific problem. But it is very likely affecting you somehow.