Can't seem to get an instanced nodes position to be followed in run time

Godot Version

Godot 4

#I’m trying to get a node to to follow an instanced scene var target_POINT = Target_point.instantiate().

But on run time the only position being recorded is the parent position @onready var trackers = get_node("../Trackers")

I’m trying to get the target_points true position instead of the parents so my enemy can tween to there instead.

func tween_to_Target_point():
	var target_POINT = Target_point.instantiate()
	var tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SINE)
	tween.tween_property(self,"global_position",target_POINT.global_position,0.5)
	print("point_position is ", target_POINT.global_position)

ALL CODE BELOW:

extends CharacterBody2D


const SPEED = 300.0
const JUMP_VELOCITY = -400.0
@onready var attack_collider_left = $"movment colliders/Left_attack_collider" 
@onready var attack_collider_right = $"movment colliders/Right_attack_collider"
var start_attack_floating : bool = false
@export var max_height: int
var has_reached_max_height: bool = false
@onready var Target_point = preload("res://Scenes/Bullseye.tscn")
@onready var Player = get_node("../Beany")
@onready var trackers = get_node("../Trackers")


# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity =0


func _physics_process(delta):
	var target_POINT = Target_point.instantiate()
	
	var target_pos = to_local(target_POINT.global_position)
	
	# Add the gravity.
	if not is_on_floor() and start_attack_floating == false:
		velocity.y += gravity * delta
	if not is_on_floor() and velocity.y <=-200:
		$"Timer".start()
	if attack_collider_left.is_colliding() or attack_collider_right.is_colliding():
		start_attack_floating = true
		attack_collider_left.enabled = false
		attack_collider_right.enabled = false

	if start_attack_floating == true:
		velocity.y += -15 
		print("is moving up and velocity.y == ", velocity.y)
		
	if velocity.y <= -max_height :
		trackers.add_child(target_POINT)
		target_POINT.position = to_global(target_pos)
		start_attack_floating = false
		velocity.y = 0
		gravity = 0
		has_reached_max_height = true

		print("reached max height")
		
		print("is looking at child position ",target_POINT.global_position, " is looking at parent position ", trackers.position   )
	if target_POINT.emit_signal("stop_looking_at_me"):
		target_POINT.stop_looking_at_me.connect(tween_to_Target_point)
		

	
	move_and_slide()
	
func tween_to_Target_point():
	var target_POINT = Target_point.instantiate()
	var tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SINE)
	tween.tween_property(self,"global_position",target_POINT.global_position,0.5)
	print("point_position is ", target_POINT.global_position)

when you .instatiate() a node, it won’t have a position, or return 0,0. Once you add it as a child to trackers, it will have the global position of it’s parent.

From your code, it looks like you are instatiating the target_point scene without any position except for the target_POINT.position = to_global(target_pos) line

How many target points do you need? You are instancing a new one during the _process function, so every frame a new one is created. Try to make one in the _ready() function instead and give it the position that it needs.

1 Like

I only need one point, I’ll move the instantiate line to _ready like you said.

The reason I only have target_POINT.position = to_global(target_pos) as the only position line is I’m trying to track the target_POINT position, not set it. reason being its a moving scene, as soon as it spawns it tracks the player position, I’ll add the code for it below.

CODE BELOW:

extends Sprite2D
signal stop_looking_at_me
signal look_at_me
@onready var player = get_node("../../Beany")
@onready var enemy = get_node("../../Enemy")
@onready var follow_timer = $"Timer"
# Called when the node enters the scene tree for the first time.
func _ready():
	follow_timer.start()


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	if follow_timer.time_left:
		self.global_position += (player.position-global_position) 
		emit_signal("look_at_me")
		print("is_following_player ", global_position)
	else:
		print("no longer following ", global_position)
		emit_signal("stop_looking_at_me")

My main issue is the fact I don’t know how to get the other node to track the targets position in run time, everything else would work just fine if I can figure out how to do it.

I tried putting the instantiate line in func _ready but it didn’t work, its back to how it was in the first post

In general, if you want to track the position of a scene that’s declared in a file, you will need to do the following:

  • Instantiate() the file
  • Add the instanced scene to the scenetree

I am a bit confused by your _physics_process() method as it instantiates the Target_point as target_POINT on every single frame but only adds the target_POINT to the scene tree at a much later point.

Please do the following:

var target_point = null

func _ready() -> void:
   target_point = Target_point.instantiate()
   add_child(target_point)

func _physics_process(delta):
   if target_point == null: return

   var target_pos = to_local(target_point.global_position)
   print("Target Point instantiated: ", target_pos)

   # Add the gravity.
   (...)

Can you check out if the prints happen with the Target Point position?

1 Like

Its now following the exact position now thankyou. I just have to edit certain parts of the code to fit this better

I got it to work thanks to both of you guys (@snipercup and @Locher ).

Here’s the new code:

ENEMY SCRIPT

extends CharacterBody2D


const SPEED = 300.0
const JUMP_VELOCITY = -400.0
signal has_locked_onto_point
@onready var attack_collider_left = $"movment colliders/Left_attack_collider" 
@onready var attack_collider_right = $"movment colliders/Right_attack_collider"
@onready var timer = $"Timer"
var start_attack_floating : bool = false
@export var max_height: int
var has_reached_max_height: bool = false
@onready var Target_point = preload("res://Scenes/Bullseye.tscn")
var target_POINT = null
@onready var Player = get_node("../Beany")
@onready var trackers = get_node("../Trackers")
@onready var bulls = get_node("../../Bullseye")


# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity =0

func _ready():
	target_POINT = Target_point.instantiate()
	add_child(target_POINT)
	target_POINT.stop_looking_at_me.connect(tween_to_Target_point)


func _physics_process(delta):
	if target_POINT == null: return
	var target_pos = to_local(target_POINT.global_position)
	print("Target_point Instantiated", target_pos)
	
	
	# Add the gravity.
	if not is_on_floor() and start_attack_floating == false:
		velocity.y += gravity * delta
	
	
	if attack_collider_left.is_colliding() or attack_collider_right.is_colliding():
		start_attack_floating = true
		attack_collider_left.enabled = false
		attack_collider_right.enabled = false

	if start_attack_floating == true:
		velocity.y += -15 
		print("is moving up and velocity.y == ", velocity.y)
		
	if velocity.y <= max_height :
		start_attack_floating = false
		velocity.y = 0
		gravity = 0
		has_reached_max_height = true
		timer.start()

		print("reached max height")
	

		print("is looking at child position ",target_POINT.global_position, " is looking at parent position ", trackers.position   )
	
	
		

	
	move_and_slide()
	
func tween_to_Target_point():
	#target_POINT.position = bulls.position
	var tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SINE)
	tween.tween_property(self,"global_position",target_POINT.global_position,0.5)
	print("point_position is ", target_POINT.global_position)



func _on_timer_timeout():
	emit_signal("has_locked_onto_point")
	print("timer timed out")

TARGET SCRIPT

extends Sprite2D
signal stop_looking_at_me
signal look_at_me
@onready var player = get_node("../../Beany")
@onready var enemy = get_node("../../Enemy")
@onready var follow_timer = $"Timer"
var can_follow: bool = false
# Called when the node enters the scene tree for the first time.
func _ready():
	emit_signal("look_at_me")
	print("is_following_player", global_position)
	self.visible = true
	can_follow = true
	enemy.has_locked_onto_point.connect(stop_following)



func _process(_delta):
	print("is not following player anymore")
	if can_follow == true:
		self.global_position += (player.position-global_position) 
	else :
		queue_free() 

func stop_following():
	self.visible = false
	print("no longer following ", global_position)
	emit_signal("stop_looking_at_me")
	can_follow = false
2 Likes