When I spawn object "Enemy" from a timer script in the main scene, the ennemy can't acces the player node and return null. But Its work proprely when an ennemy is added direcly to the scene.

Here the main node with all the child items.

Timer script =>

extends Timer
var enemy1 = preload("res://Enemy.tscn")
var x = -107
var y = -107
var cnt 

func _ready():
	pass
func _on_Timer_timeout():
	print("spawn")
	x+=10
	y+=10

var Player = get_parent().get_node("Player")
if(Player != null):
	var enemy1_instance = enemy1.instance()
	enemy1_instance.position = Vector2(x,y)
	add_child(enemy1_instance)
			
wait_time = 2;

Enemy Script=>

extends KinematicBody2D
var motion = Vector2()
var player = null

func _ready():
	pass

func _physics_process(delta):
	var player = get_parent().get_node("Player")
	if player !=null:
		position += (player.position - position)/50
		look_at(player.position)
		move_and_collide(motion)
	else:
		print("playerNull")

func _on_Area2D_body_entered(body):
	if "Bullet" in body.name:
		queue_free()

In the func _physics_process(delta) if the enemy is dynamicaly generated from the timer script var player = get_parent().get_node("Player") return null...

Thank you for helping me

  • get_tree().get_root() should return a Viewport, not your World node. You might want to add a variable to your timer:

    var world
    
    func _ready():
    	world = get_parent()

    and use that instead.

get_tree().get_root() should return a Viewport, not your World node. You might want to add a variable to your timer:

var world

func _ready():
	world = get_parent()

and use that instead.

    One thing I see there is you are getting your player variable in the process function. First of all the variable was declared already at the top of the script, so you wouldn't want to declare it again, and it doesn't make sense to do so in the process that I can see. I would also get the node in the ready function because there might be a delay getting it and there is no reason to get it over and over again in process.

      fire7side Yes, at first it was just declare in the func. My bad, you are true.

      Also, relative paths are not a great idea for dynamically generated nodes (unless you are sure they will always be on the same parent node). You could do this:

      var player
      
      func _ready():
      	player = get_node("/root/World/Player")
      
      func _physics_process(delta):
      	if is_instance_valid(player):
      		# do your update here

      Which will always work as long and the nodes "World" and "Player" are not moved or renamed.

      Another approach: In Godot 3.5+, you can make Player a "Scene Unique Name" (aka Scene Unique Node) and access it as $"%Player" from anywhere in the scene.