World's script:

func _process():
         var path_go = $Navigation2D.get_simple_path($Enemy.position,$Player.position)
         $Enemy.path = path_go

Enemy's script:
func _process():
          velocity = speed * delta
          while  velocity > 0 and path.size() > 0:
		var distance_to_target = position.distance_to(path[0])
		if velocity <= distance_to_target:
			position += position.direction_to(path[0]) * velocity
			$Player_animation.play("run")	
		else:
			position = path[0]
			path.remove(0)
		velocity -= distance_to_target

I'm making the enemy find the player themselves, but they know to dodge obstacles by themselves, using Navigation2D which is a child of World and NavigationPolygonInstance which is a child of Navigation2D. According to my code above, it's pretty good. But there is a problem is how and where should I add the line of code so that when the Player goes behind Enemy, Enemy knows to turn around. Don't use Flip, but use Scale.x so it can bring collisions. So how do I insert the code and where do I insert it to do it all? And I want all the characters of the Enemy group to have to find the Player when they are created in the World. Because according to my code I can only make one enemy find the Player and dodge the obstacles. And if I want all the Enemies in the Enemies group to simultaneously look for the Player, the above code doesn't seem to work. Someone please help me. Thank you very much.

    Megalomaniak changed the title to Flip by scale.x and enemies Group chase Player (enemy know to avoid Obstacles! .

    I see a few things that might be the problem. You forgot to place delta in the process argument. A while loop won't work, you need to move just by a little each frame. Velocity will always be non-zero, so you don't have to check that. And I cleaned up a few things.

    func _process(delta):
              velocity = speed * delta
              if path.size() > 0:
    		var distance_to_target = position.distance_to(path[0])
    		if velocity <= distance_to_target:
    			position += position.direction_to(path[0]) * velocity
    			$Player_animation.play("run")	
    		else:
    			position = path[0]
    			path.remove(0)

    It didn't work, and Enemy froze. I mean in the above code, where should I insert the code scale.x = -1 or scale.x = 1 so that when Enemy moves to chase Player when velocity.x flip the scale also flip (animation + collision)? Because if it's a normal move and scale flip, I already know how to do it, but in this case it's a move that chases the Player and knows how to dodge obstacles, so I don't know how to do it. The method I do is already presented above. Navigation2D -> Navigation2DPolygonInstance. Hope you help me.Thank you!

    You can put the get_simple_path() function in the enemy script. So each enemy can get their own shortest path to the player.

    • Odin replied to this.

      yikescloud because this way uses Navigation2DPolygonInstance and it must be in the World node. If you put the simple_path function in an Enemy node, you must use Navigation2D by Tilemap. But the way Tilemap is too complicated for me. Do you have a way in this direction that is simple? Or simply code in Tilemap style. Because the clips on Youtube make the Tilemap style so confusing.

        Odin You can use it in the enemy. Just like this:

        extends KinematicBody2D
        onready var nav:Navigation2D = get_node("../../NavigationPolygon")
        
        func _process(delta):
            nav.get_simple_path(self.position,$Player.position)
        • Odin replied to this.

          yikescloud Unfortunately it doesn't work. If OK, can you give me an example code to help me in that case?Sincerely thank you very much. Sorry I'm new to coding too. ^^

          I just do this in my game, I use both navigationPolygonInstance and Tilemap same time, it's below the navigation2D node, and it just works fine.

          func navigate_point(var _p:Vector2) -> Vector2:
          	var _path = _Navigator.get_simple_path(position, _p)
          	if _path.size() > 1:
          		return _path[1]
          	return _p

          Yeah, that's great. I really appreciate your great help, Yike! Sorry for my trouble.World's Script? Enemy's Script? What's the full take on this, Yike? I wonder if you'd be willing to show me the full code on this issue for me? All are just code related to this problem only.Once again thank you very much for your help. Best regards!

            Odin You dont need a world script for this. Later I will upload a demo project maybe

            • Odin replied to this.


              It still gives me a lot of errors, Yike? Is something wrong? This is the project you sent me. How will I fix it? and if i want Enemies to not only chase every Player, but they also chase everyone in the Player group, how do I add the which code? Using Groups? Sorry to bother you Yike! ^^

                Odin
                Fix the Error: change script in NavigationPolygonInstance like this:
                func draw_self():
                for i in navi_poly.get_outline_count():
                var _outline:PoolVector2Array = navi_poly.get_outline(i)
                if _outline.size() == 0:
                continue
                _outline.append(_outline[0])
                draw_polyline(_outline, Color.white, 5.0, false)

                Seems like get_polygon_count () return count of triangles but not the island.

                If you want chase other, just change this code in enemy process:

                var p = navigate_point(_Player.position)
                to
                var p = navigate_point(_player_group.get_nodes_in_group[player_index])

                • Odin replied to this.

                  yikescloud
                  That error is gone, now only the error on row 14 in Enemy's Script. Now what Yike?

                    Odin Just comment this like you select. I thought I commented it already, maybe you uncomment it again?