• Godot Help
  • The _on_area_entered sometimes doesn't work

Hi!
I tried to upload a video that shows my issue but I couldn't 😉
Anyway, I use area2d for the shots of my player.
And also area2d for the enemies I use in the game.
Sometimes the _on_Orc_area_entered is working and sometimes it doesn't.
I use collisionshape2d for both of them and made sure that the collision shape envelops their sprites correctly.
Thank you for your help!

    Sonadrin this is never going to work. don't test for node names. nodes instantiated in game are renamed.

    use groups instead. put your shot into a "damage" group (or whatever you like) and test if the are is in the group:
    if area.is_in_group("damage"):

      Jesusemora Also you could use classes, more readable imo. Groups live in editor somewhere where its not obvious, while class definition is in the script taht is attached to the node.

      if area is damage:

      • xyz replied to this.

        kuligs2 Also you could use classes, more readable imo. Groups live in editor somewhere where its not obvious, while class definition is in the script taht is attached to the node.

        That'd require attaching a script which may be an overkill if needed only for simple identification. Groups are better suited for this. Our scientists know exactly where they live - in the SceneTree object. From the docs:

        You can also use the SceneTree to organize your nodes into groups: every node can be added to as many groups as you want to create, e.g. an "enemy" group. You can then iterate these groups or even call methods and set properties on all the nodes belonging to any given group.

        Thank you all for the fast answers!
        Do you think that it sometimes works because the nodes are renamed?
        Because again, sometimes the shots don't hit the enemies but after a while they do.

        I will anyway change the code the way that you guys suggested because it sounds like a good practice to do it.
        So groups are for small projects and classes are for bigger ones?
        It's confusing to know when I should use them.

          Sonadrin I guess what @xyz trying to say, where you dont need to attach scripts to node but want to refer to a sort of you use groups, where you need to execute a script and attach one then use class_names..

          Idk.. i dont like groups because i dont see them in script.. so after months i might forget what obj is in what group..

          Same thing with control bindings - actions. I define them in a script and then use it on autoload.

          example_input_actions.gd

          extends Node
          
          var key_controls = {
          				"action_move_right": [KEY_RIGHT, KEY_D],
          				"action_move_left": [KEY_LEFT, KEY_A],
          				"action_move_forward": [KEY_UP, KEY_W],
          				"action_move_backward": [KEY_DOWN, KEY_S],
          				"action_jump": [KEY_SPACE],
          				"menu_main": [KEY_ESCAPE],
          				"action_sprint": [KEY_SHIFT],
          				}
          var mouse_controls = {
          				"action_mouse_left": [MOUSE_BUTTON_LEFT],
          				"action_mouse_right": [MOUSE_BUTTON_RIGHT],
          				"action_mouse_middle": [MOUSE_BUTTON_MIDDLE],
          				"action_mouse_w_up": [MOUSE_BUTTON_WHEEL_UP],
          				"action_mouse_w_down": [MOUSE_BUTTON_WHEEL_DOWN],
          				}
          
          func _ready():
          	add_key_inputs()
          	add_mouse_inputs()
          	pass # Replace with function body.
          
          # Called every frame. 'delta' is the elapsed time since the previous frame.
          func _process(_delta):
          	pass
          
          func _unhandled_input(_event):
          	if Input.is_action_pressed("menu_main"):
          		# Quits the game
          		get_tree().quit()
          	pass
          
          func create_key_action(action_name:String,keycode:int):
          	InputMap.add_action(action_name)
          	var k = InputEventKey.new()
          	k.keycode = keycode
          	InputMap.action_add_event(action_name,k)
          	pass
          
          func add_key_inputs():
          	var ev
          	for action in key_controls:
          		if not InputMap.has_action(action):
          			InputMap.add_action(action)
          		for key in key_controls[action]:
          			ev = InputEventKey.new()
          			ev.keycode = key
          			InputMap.action_add_event(action, ev)
          			
          func add_mouse_inputs():
          	var ev
          	for action in mouse_controls:
          		if not InputMap.has_action(action):
          			InputMap.add_action(action)
          		for key in mouse_controls[action]:
          			ev = InputEventMouseButton.new()
          			ev.button_index = key
          			InputMap.action_add_event(action, ev)

          Wow guys it worked!
          For now I just added the shot to the weapons group i created as @Jesusemora said.
          I did it now because it was faster.
          I think what you said @kuligs2 is interesting.
          I'll might do it. just to make sure I won't forget what obj is in that group later as you said.
          Thank you @xyz also!

          Sonadrin Do you think that it sometimes works because the nodes are renamed?

          It likely works whenever you instantiate the scene while no other instances of the same scene exist. Then the engine will name the instance exactly how the scene is called. However if the instance with that name already exists, the subsequent instances will have some suffix added to the name, to make the name unique. Look into the remote scene tree at runtime to see how your instances are named by the engine.

          Anyway, listen to what @Jesusemora said. Groups are the way to go here.