Enemy Following Player

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ThreeSpark

I am trying to get an enemy in my game to follow my player. Here is my code:

extends KinematicBody2D

onready var player_scene = preload("res://Player.tscn")
var velocity = Vector2()
var speed = 400

func _ready():
	var player = player_scene.instance()
	add_child(player)
	
func _process(delta):
	if $player.position.x < position.x:
		velocity.x -= speed
		
func _physics_process(delta):
	velocity = move_and_slide(velocity * delta)

However, it won’t open and the error message is “Invalid get index ‘position’ (on base: ‘null_instance’)” Does anyone know what I am doing wrong?

:bust_in_silhouette: Reply From: kidscancode

Note: Please format your code using the {} button or by placing four spaces in front of each line. I edited your post to fix it.

Your error is happening on line 12 where you have $player.position.x. $ is a shorthand for get_node(), which finds a node using the node’s name property.

“null instance” errors typically happen because you have the node path incorrect. In this case you’re not getting the player node, because “player” is not the node’s name. When instancing, node names are set automatically by the engine. Since you’re already instancing it and assigning it to the variable player, you could make player a class variable and use it instead of get_node(): player.position.x

However, you’re going to find you have another problem: the node this is running on is a KinematicBody2D which you apparently want to move around (I’m guessing it’s an enemy). When a node moves, so do all of its children. Therefore, you are going to have a problem if you make the player a child of this node, as the player will now be “attached” to it. You want your player and enemy objects to be independent of each other, not locked together.

How could I make the enemy follow the player? I am also making two players (the scene for player one is Player and the scene for player 2 is Player2), so how would I make the enemy target the nearest player instead of target a specific player?

ThreeSpark | 2018-07-29 20:05

Those are very different questions. To have the player and the enemy both on the screen, you need to instance both of them in a “main” scene. Then the enemy can target the player by using its node reference. For example, if this was your tree:

Main (Node or Node2D)
-- Player
-- Enemy

Then in the enemy script you can reference the player by using get_node('../Player')

kidscancode | 2018-07-29 20:12