Godot Version
v4.3.stable.official [77dcf97d8]
Question
I have a gun node2d that instantiates a projectile node2d that contains a rigidbody3d. When the projectile fires it as a TimeToLive, and when it expires, the projectile removes itself from the current tree and puts itself in a “magazine” array in the gun that spawned it. Then when the gun fires again, if it has a projectile in the magazine, instead of instantiating it, it re adds it to the current tree and positions it to be fired again.
The problem comes when the projectile collides with a staticbody2d. It removes itself from the tree and adds itself to the magazine just fine. But when I try to add it back to the scene tree and move it to the firing position, it is still colliding with the same staticbody2d.
Here is what I think is the relevant code in the gun
func _shoot():
_curr_reload = 0
var current_projectile
if magazine.size() > 0:
print ("Magazine")
current_projectile = magazine.pop_back()
else:
print ("New")
current_projectile = projectile.instantiate()
current_projectile.chamber(shooter.global_position, self)
current_projectile.shoot(Vector2.RIGHT.rotated(rotation), player.linear_velocity)
get_tree().get_current_scene().get_node("Projectiles").add_child(current_projectile)
And here is the projectile object
func chamber (start_pos, gun):
$RigidBody2D.global_position = start_pos
_parent_gun = gun
func shoot( direction, inherited_inertia):
_life = 0
$RigidBody2D.linear_velocity = direction * projectile_speed
_in_flight = true
func _physics_process(delta: float) -> void:
print (rigid_body_2d.get_colliding_bodies(), _in_flight)
if _in_flight :
if _life < ttl:
_life += delta
if _life >= ttl:
_recycle()
if rigid_body_2d.get_colliding_bodies().size() > 0:
hit (rigid_body_2d.get_colliding_bodies()[0])
func hit (node : Node):
_recycle()
if node.is_in_group("TakesDamage"):
node.take_damage(projectile_damage)
func _recycle():
_in_flight = false
rigid_body_2d.global_position = Vector2.ZERO
print (rigid_body_2d.get_colliding_bodies(), _in_flight)
get_tree().get_current_scene().get_node("Projectiles").remove_child(self)
_parent_gun.magazine.append(self)
The order of operations is the gun gets the shoot input, tries to pull the projectile from the magazine, and if it doesn’t exist instantiates it. Then it passes the projectile the starting position and direction. The projectile sets those values and then sets the _in_flight flag to true so the _physics_process will start testing if the rigidbody2d is colliding. Once it hits a node, it passes that node the damage if it can “take damage”, then zeros out its position then removes itself from the current tree and puts itself in the gun’s magazine.
When I run the game and fire the first bullet I get the output []true
every frame until it hits an staticbody2d. Then I get [StaticBody2D:<StaticBody2D#33353106822>]true
which makes sense, that is the object colliding with and the projectile is still in flight. But then I get [StaticBody2D:<StaticBody2D#33353106822>]false
from the _recycle() function. Even though I have zeroed out the global position, moving the projectile away from the staticbody2d, it is still detecting the collision.
Is there some sort of cache in the rigidbody2d that I need to clear of colliding bodies to get it to stop detecting the previous collisions?