0 votes

Hello, I'm making a game where if enemy getting hit, he disappears. All bullets are new instances of an object, enemies too. Enemies have this code:

func _on_Enemy_body_entered(body):
    if body == get_node("/root/Main/Bullet"):
        queue_free()

And it works, but not always, sometimes i got this error in the debugger

Node not found: /root/Main/Bullet

How can i make this work properly?

in Engine by (15 points)

Could your code which frees the enemy nodes also be freeing the bullet nodes? Maybe there's other code which trying to free the bullet nodes, but they're already being freed by the enemy code.

I'm trying to free enemie nodes, not the bullets. I dont have any other code to free enemie nodes. I tried to do all this in the main node, result still the same. Even if I use has_node I only get rid of error message. My enemies not disappearing sometimes.
P. S. sorry for my english it's not my native lang

2 Answers

+2 votes
Best answer

Add your bullet scene to the "bullet" group, then check if body.is_in_group("bullet").

Do not use names because repeated names will be changed by the engine when adding to the tree (look at the remote scene tree when running the game), also try to avoid hardcoded paths because that will break every time you remake the scenes or add new bullet types.

Groups are flexible because you can assign to any kind of node that will behave in a similar way.

by (7,874 points)
selected by

Thank you for your answer and the advice, it works great!

+1 vote

You will only ever have one bullet at the path "/root/Main/Bullet". This bullet is named "Bullet".

Other bullets that are added to your scene will be called "Bullet2" and "Bullet3". Godot auto-numbers them. They will not be recognized by your code, since your code only looks for "Bullet".

So, if you ever have more than one bullet, your code isn't going to work properly.

For example, if you have two bullets on screen named "Bullet" and "Bullet2", and Bullet is freed before Bullet2 enters the enemy, then you are going to get an error since your code is looking for Bullet, which no longer exists.

Try this instead:

func _on_Enemy_body_entered(body):
    if "Bullet" in body.name:
        queue_free()
by (1,557 points)

Thank you, it works, but I think eons solution is better in my case.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.