- Edited
sorry for weird title... I've got a bit of a strange bug here in my code, and I'm not quite sure what i did wrong.
The situtation: I'm trying to implement a scene change/ doorway system, so that my character can change rooms by being in the correct area and pressing a certain button.
i have 2 variables exported on the door, one that links to what scene the door IS in, and one that links to what scene the door GOES to. Both of these have string values just listing paths- I don't know if this is the best way to do this, but its the one I tried.
Then, inside my scene change (deferred) function, I have get the doors / nodes tagged 'door', and look at them with a for loop to see if they match my old door...
Here's the weird part! the code works ~perfectly~ when I only have one door in a scene, but when I test with 2 doors, it messes up.
I get an error saying that I cannot compare a string and an object with a == operator.
I printed out the different variables to test this, and funnily enough, inside the for loop (and not before it - i printed out the same variable mutliple times through the code) is when it DOES appear as an object. ... this strikes me as really weird. I know I messed up somewhere, I just cannot for the life of me find out where.
Okay thanks for reading all that _ now i'll post the code I'm using:
the script on teh door way:
extends Area2D
#setting as test scene by default, CHANGE LATER
export var scene_door_leads_to = "res://Scenes/TestScene.tscn"
export var scene_we_came_from = "res://Scenes/BigRoom.tscn"
var player
var can_open_door #see if we can open this door! this can come in handy for keys later!
var is_in_door #To see if we are in or out of the door!
#this is so we can have any easy ref to waht door we just came from
#in our global/ autoload scene manager script
signal where_did_we_come_from(where_we_came_from)
signal where_is_player(player)
# Called when the node enters the scene tree for the first time.
func _ready():
player = null
self.connect("where_is_player", SceneManager, "return_player")
self.connect("where_did_we_come_from", SceneManager, "found_our_door")
can_open_door = false
print (scene_door_leads_to)
print (scene_we_came_from)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if Input.is_action_pressed("open_door") and can_open_door:
move_rooms()
#we may need to move this code to another func
#cuz atm it will only transfer u when u JUST enter and have the righ tkey pressed...
#now the func to actually hold our move room code~!
func move_rooms():
emit_signal("where_did_we_come_from", scene_we_came_from)
print (scene_we_came_from)
SceneManager.goto_scene(scene_door_leads_to)
#when we enter the door we are inside it!
func _on_Doorway_body_entered(body):
if body.is_in_group("Player"):
is_in_door = true
#So we can keep the ref to plaeyr outside area 2d func
func find_player(playerskb):
player = playerskb
#I... dont think I'm using this rn. its just here from an old attempt
func return_player():
if player != null:
print ("we foudn player from the doorway script")
print (player)
else:
print ("we did not find plaeyr from doorway script")
return player
func _on_TimerTilReopenDoor_timeout():
can_open_door = true
#when we exit the door we can say we are not in the door
func _on_Doorway_body_exited(body):
if body.is_in_group("Player"):
is_in_door = false
and the scene manager's script:
extends Node
#memo to self: this script AUTO LOADS! (if i did it right)
#memo to sellf: ANY NODE may connect to or emit signals in an AUTOLOAD script
#NOTE
#When changing scene, we will need this code:
#SceneManager.goto_scene("res://scene_name.tscn")
var current_scene = null
var player_to_spawn = null
var door_we_came_from = null #this is different than current scene in application-\
#we use it to check what the door SAYS we came from.
#current scene is just got when we load the game!!!!
var players_pos = Vector2(0.0, 0.0)
# Called when the node enters the scene tree for the first time.
func _ready():
var root = get_tree().get_root()
current_scene = root.get_child(root.get_child_count() - 1)
#this is assuming the player is always a DIRECT child of the root!!!!
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass
func goto_scene(path):
#we MUST defer this or there could be weird behavior!!!!
#so thats hwy we type the next line
call_deferred("_deferred_goto_scene", path)
func _deferred_goto_scene(path):
#before we free the scene we need to find out where we came from!!!
#take 2 with the code
#we need to save where we came from
#and now where we are going to!
var current_scenes_doors = get_tree().get_nodes_in_group("door")
var current_door
var current_scene_name
for i in range(current_scenes_doors.size()):
#this line ONLY complains when there is more than one dooor.... :<
if current_scenes_doors[i].scene_we_came_from != null:
print (current_scenes_doors[i].scene_we_came_from)
print (door_we_came_from)
print (typeof(door_we_came_from))
# var type_of_door = typeof(door_we_came_from)
# if type_of_door == 17:
# print ("we have an object not a string")
#so atm the first run through on big room we get a string
#BUT
#the second run through we get an object???
if current_scenes_doors[i].scene_we_came_from == door_we_came_from:
current_door = current_scenes_doors[i]
door_we_came_from = current_door
current_scene_name = current_door.scene_we_came_from
if current_door.has_signal("where_is_player"):
player_to_spawn = current_door.player
#so we are freing this too so we need a new ref to it!!!!!
#NOW we can remove the current scene!
current_scene.free()
#WE ARE JUST COPING PATHS FROM THE FILESYSTEM
#load the new scene
var s = ResourceLoader.load(path)
#instance the new scene
current_scene = s.instance()
#add it to the current scene, as a child of root
get_tree().get_root().add_child(current_scene)
#this is OPTIONAL but will make it compatible with Scene_Change.change_scene() API
get_tree().set_current_scene(current_scene)
#now we need a bit of logic to find out what door we are IN and spawn us there
var doors = get_tree().get_nodes_in_group("door")
var spawnpoint
for i in range(doors.size()):
#we're in a new room now so this door needs to see if the door goes
#back to whence we came
#ah. this doens't work b/c one is a scene and one is a string
# if door_we_came_from != null:
if doors[i].scene_door_leads_to == current_scene_name:
spawnpoint = doors[i]
if spawnpoint != null:
#player_to_spawn = spawnpoint.player #oh dun this wont work cuz we only find
#player when they enter our area2d!!!
var array_for_player = get_tree().get_nodes_in_group("Player")
player_to_spawn = array_for_player[0] #Just get the first thing tagged player. there should only be one
spawn_player(player_to_spawn, spawnpoint, door_we_came_from)
func spawn_player(player, door_to_spawn_from, door_we_came_from):
var new_player = player #Just testing ...i think this is useless now that I got this test working!
var new_pos = door_to_spawn_from.position
# if door_we_came_from != null:
# #if we are not trying to reenter our current scene
# if door_to_spawn_from != door_we_came_from:
new_player.position = new_pos
func found_our_door(door):
print (door)
door_we_came_from = door