A packed scene instanced works the same way than an instance scene in script?

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

Hello guys:
A packed scene instanced works the same way than an instance scene in script?
I have 2 scenes Navigation 2d scene and Player Scene:
Navigation 2d (with script)
Line2d
Player (instanced)
Navigation2d script: https://ibb.co/ZTpj31c

Player Scene:
Kinematicbody2d (with script)
CollisionShape2D
Sprite
Player scene script: https://ibb.co/gd1G6rW

I want to delete the instanced player in the navigation 2d scene so in the navigation 2d script I packed the player scene and instanced in order to get access to the player script variables ( position and path ( var path =PoolVector2Array () (determined in the player script ).
https://ibb.co/0V2rSbq
But with the packed scene it doesn’t work the same way:
https://ibb.co/mqkZ1j8
So my questions are:

  1. A packed scene instanced works the same way than an instance scene in script?
  2. Is there anyway to get position or another variable of one node from another scene tree that has a script attached without having to pack the scene?
    I know var player_position = get_node (“/root/Player”).instance
    But this is doesn’t let me get position or a variable after instance.

Thanks for your help

:bust_in_silhouette: Reply From: Inces

I am a bit confused :slight_smile:

So Your navigation node has player as a child, but You want to delete its Player and use another one, but get variables from the first one ?

Generally both your players are instanced. There is one instance being child of navigation set in editor, and another instance, called from script based on packedscene. So they are two instances of one scene. They share every aspect of code, but their private variables will be different. Player nr1 is introduced in editor, You placed him somewhere in the viewport, so he has certain global_position. Player nr2 has been instanced in script and his position was never set, so it is default Vector2.ZERO. Player nr1 is a child of navigation, so his transform depends on navigation transform, Player nr 2 is orphaned, and is independent from any local position. The same goes for every export variable.

I guess You wanted to get actual path and position of Player. You should use reference for actual Player then, but why do you want him deleted ??

Hello, thanks for your answer, I’ll try to explain myself better :slight_smile:

So Your navigation node has player as a child, but You want to delete
its Player and use another one, but get variables from the first one ?

What I’m trying to do is instancing the player by code in the navigation2d scene but not by adding it manually in the scene tree. I instanced the player using this code in the navigation 2d script:

  extends Navigation2D

    onready var player = preload ("res://Player.tscn").instance()
    
    func _unhandled_input(event):
    	if event is InputEventMouseButton:
    		if event.button_index == BUTTON_LEFT and event.pressed:
    			var path = get_simple_path(player.position, event.position,false)
    			$Line2D.points = path
    			player.path = path

And after instanced by code when i write the code i can get the player.position and the player.path variable assigend in the player script:

Player script:

extends KinematicBody2D

var speed = 50
var path : = PoolVector2Array()

func _process(delta):
	# Calculate the movement distance for this frame
	var distance_to_walk = speed * delta
	
	# Move the player along the path until he has run out of movement or the path ends.
	while distance_to_walk > 0 and path.size() > 0:
		var distance_to_next_point = position.distance_to(path[0])
		if distance_to_walk <= distance_to_next_point:
			# The player does not have enough movement left to get to the next point.
			position += position.direction_to(path[0]) * distance_to_walk
		else:
			# The player get to the next point
			position = path[0]
			path.remove(0)
		# Update the distance to walk
		distance_to_walk -= distance_to_next_point

But I don’t know why it doesn’t work well. So in order to work well I need to manually instanced the player in the navigation 2d scene and in the script just take the instanced player.

extends Navigation2D

onready var player = $Player


func _unhandled_input(event):
	if event is InputEventMouseButton:
		if event.button_index == BUTTON_LEFT and event.pressed:
			var path = get_simple_path(player.position, event.position,false)
			$Line2D.points = path
			player.path = path

So my question is :what is the diference between manually instancing the player in the navigation scene and then in the navigation2d scene using this code to get the player variable and position:

onready var player = $Player 

Than instancing the player by script and using this piece of code to get the player variable and position:

 onready var player = preload ("res://Player.tscn").instance()

I don’t get why it works in one way and not in the other one.

project:

Navigation2D-Completed.rar - Google Drive

Maranpis | 2021-11-29 22:17

Simple answer… because your player node is not a part of the sceneTree in the second example.

Do

add_child(player)
#>> then path get code here <<

Wakatta | 2021-11-30 03:42

Hello Wakatta, thanks for your answer :slight_smile:

Mi idea is to open a new scene and instance the player and the navigation 2d separately:
Node 2d (main node)
navigation 2d (instanced)
Player (instanced)

So this is why I don’t want to add the player as a child of the navigation 2d scene, but I want to be able in the navigation 2d script to access the player’s script variables path and position. So I instanced the scene in the navigation 2d script.

But when I create a new scene and instanced both, it doesn’t work, and I don’t know why. Only work if the player is added as a child in the navigation2d scene and the instanced in the new scene.

Why is that?

Navigation2D-Completed.rar - Google Drive

Maranpis | 2021-11-30 19:41

The player node will work wherever you add it but it must be a part of the screenTree to get the variables you seek.

You can add the player node to another node by reference then get the path and position variables. It does not have to be added as a child of navigation2d

┖╴Main (Node2D)
  ┠╴Player (KinematicBody2D)
  ┖ Map (Navigation2D)

If the navigation node creates the player node then

onready var player = preload("res://Player.tscn").instance()

func _ready():
    get_parent.add_child(player)

func _unhandled_input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            var path = get_simple_path(player.position, event.position,false)
            $Line2D.points = path
            player.path = path

Wakatta | 2021-11-30 22:56

Thanks, I think is a bit more clear now :slight_smile:

Maranpis | 2021-12-01 06:17