Hey,<br /><br />I've got my character set up in it's own scene (imported as an instance in the main scene) with a script attached to control the character nodes. However, when I call get_node("path/to/node") in the script I get a node not found error even though the node exists and the path is correct. I've littered my functions with null checks:<br />

<br /><br />func set_eyes(new_value):<br /> if get_node("Eyes") != null:<br /> eye_colour = new_value<br /> eye_offset = eye_types[eye_colour]<br /> get_node("Eyes").set_frame(eye_offset + direction_offset)

<br />And the script works fine and suppresses all but the first error message for each node I'm trying to fetch. The example function is called both in the game and as a setget. I figure I must be doing something wrong because there must be a way to call get_node() without getting an error and without requiring null checks. <br /><br /><br />Thanks in advance!

Are these get_nodes called during the ready function by any chance? The ready function generally fires twice, and the first time is before any of the nodes are initialized.

[quote author=Ross link=topic=15585.msg16611#msg16611 date=1465177192]Are these get_nodes called during the ready function by any chance? The ready function generally fires twice, and the first time is before any of the nodes are initialized.[/quote]Small correction, the [tt]ready[/tt] function does not fire twice, only once when the node enters (or reenters) the scene tree (and after all newly entered nodes have called their [tt]enter_tree[/tt] callback if any).But indeed, if this [tt]set_eyes[/tt] function is called during [tt]_ready[/tt], it can be that the "Eyes" child node hasn't been instantiated yet, and thus the code fails.

Thanks for the info. Unfortunately that doesn't seem to fix it. It makes no difference if the the function is called in [tt]ready[/tt] or not, I still get the error. It's not game breaking, as it only fails on the first loop, then works as it should. From what you've both said, I guess it's being called early, but the curious thing is that the function isn't called until the player presses a key and nowhere else is calling it. Could it be because [tt]set_eyes[/tt] is also a tool function used with setget? So it gets called when the game starts?Here's the full script:[code]toolextends Node2Dexport(String, "Down", "Left", "Right", "Up") var facing = "Down" setget set_directionexport(String, "White", "Pale", "Brown", "Orange", "Grey", "Blue", "Green", "Red") var skin_colour = "White" setget set_skin_colourexport(String, "Blue", "Green", "Brown", "Narrow", "Deamon", "Blood", "AnimalYellow", "AnimalGreen") var eye_colour = "Blue" setget set_eyesexport(String, "None", "Long", "Medium", "Short", "Large") var beard_style = "None" setget set_beard_styleexport(String, "Grey", "Blonde", "Black", "Brown", "Ginger", "Red", "Green", "Blue") var hair_colour = "Grey" setget set_hair_colourexport var wrinkles = false setget set_wrinklesvar skin_colour_offsets = { White = 0, Pale = 4, Brown = 8, Orange = 12, Grey = 16, Blue = 20, Green = 24, Red = 28, }var eye_types = { Blue = 64, Green = 68, Brown = 72, Narrow = 76, Deamon = 80, Blood = 84, AnimalYellow = 88, AnimalGreen = 92, }var facial_hair_offsets = { Long = 96, Medium = 128, Short = 160, Large = 192, }var hair_colour_offsets = { Grey = 0, Blonde = 4, Black = 8, Brown = 12, Ginger = 16, Red = 20, Green = 24, Blue = 28 }var head_offset = 0var wrinkles_offset = 32 var eye_offset = 64var direction_offset = 0var beard_offset = 96var hair_colour_offset = 0var current_animation = nullvar new_animation = nullfunc ready(): passfunc set_beard_style(new_value): if get_node("Beard") != null: print("setting beard") beard_style = new_value if beard_style == "None": get_node("Beard").hide() return beard_offset = facial_hair_offsets[beard_style] get_node("Beard").set_frame(beard_offset + hair_colour_offset + direction_offset) get_node("Beard").show() func set_hair_colour(new_value): if get_node("Beard") != null: hair_colour = new_value hair_colour_offset = hair_colour_offsets[hair_colour] set_beard_style(beard_style)func set_skin_colour(new_value): if get_node("Head") != null: skin_colour = new_value head_offset = skin_colour_offsets[skin_colour] get_node("Head").set_frame(head_offset + direction_offset) get_node("Wrinkles").set_frame(wrinkles_offset + head_offset + direction_offset)func set_eyes(new_value): if get_node("Eyes") != null: eye_colour = new_value eye_offset = eye_types[eye_colour] get_node("Eyes").set_frame(eye_offset + direction_offset)func set_direction(new_value): if get_node("Animation") != null and get_node("Eyes") != null and get_node("Head") != null: facing = new_value if facing == "Down" and direction_offset != 0: direction_offset = 0 get_node("BackFacing").hide() get_node("FrontFacing").show() get_node("SideFacing").hide() elif facing == "Left" and direction_offset != 1: direction_offset = 1 get_node("SideFacing").set_scale(Vector2(1,1)) get_node("BackFacing").hide() get_node("FrontFacing").hide() get_node("SideFacing").show() var sword = get_node("SideFacing/FrontArmUpper/FrontArmLower/Sword") get_node("SideFacing/FrontArmUpper/FrontArmLower").remove_child(sword) get_node("SideFacing/BackArmUpper/BackArmLower").add_child(sword) elif facing == "Right" and direction_offset != 2: direction_offset = 2 get_node("SideFacing").set_scale(Vector2(-1,1)) get_node("BackFacing").hide() get_node("FrontFacing").hide() get_node("SideFacing").show() var sword = get_node("SideFacing/BackArmUpper/BackArmLower/Sword") get_node("SideFacing/BackArmUpper/BackArmLower").remove_child(sword) get_node("SideFacing/FrontArmUpper/FrontArmLower").add_child(sword) elif facing == "Up" and direction_offset != 3: direction_offset = 3 get_node("BackFacing").show() get_node("FrontFacing").hide() get_node("SideFacing").hide() get_node("Head").set_frame(head_offset + direction_offset) get_node("Wrinkles").set_frame(wrinkles_offset + head_offset + direction_offset) get_node("Eyes").set_frame(eye_offset + direction_offset) if beard_style != "None": get_node("Beard").set_frame(beard_offset + hair_colour_offset + direction_offset)func set_wrinkles(new_value): if get_node("Wrinkles") != null: wrinkles = new_value if wrinkles: get_node("Wrinkles").show() else: get_node("Wrinkles").hide()[/code]

19 days later

As the other posters have said, the timing is off on that first call.  For some reason the node isn't there but by the time any subsequent calls are made the node IS there.  I'm not sure about the timing issue, but to get rid of the error use [tt]has_node[/tt] instead of [tt]get_node[/tt] and then checking for [tt]null[/tt]

12 days later

Odd, all the other scripts work fine, just that one.Anyway, [tt]has_node()[/tt] works a charm, no more error messages! Thanks!  :D

6 years later