ColorRect disappears out of NOWHERE at runtime

Godot Version

4.3.stable

Question

I was trying to make a cutscene in my game, and in it i would change the modulate of a ColorRect in order to obfuscate everything that was going on underneath. The thing is, the script that would do that does not find it and says that it’s a “null instance”. I’m sure the ColorRect is not referenced by any other script that might edit it’s name and/or delete it because i tried changing its name in the editor, deleting and re-making it with a different name (and updating the name in the script of course), and even iterate through all single nodes in the scene and printing them to the console. I had no luck. The fated ColorRect keeps disappearing and i am going insane.

Could you show your script, scene tree, and exact error message/output?

this is the function (that i keep inside a singleton) that tweens the overlay color

func tween_node_modulate(node: CanvasItem, result: Color, time: float):
	print("node is ",node)
	var color_data = [result.r, result.g, result.b, result.a]
	var start_data = [node.modulate.r, node.modulate.g, node.modulate.b, node.modulate.a]
	var step = []
	var i = 0
	while(i<=3):
		step.append( (color_data[i]-start_data[i])/time ) #sets the step
		i += 1
	modulate_queue[node] = [step, start_data, color_data]

which later works when called from _process

func _process():
	for node in modulate_queue.keys():
			var data = modulate_queue[node]
			
			if _calculate_arrays_difference_magnitude(data[1], data[2]) > 0.05:
				data[1] = _sum_arrays(data[0], data[1], delta)
				node.modulate = Color(data[1][0], data[1][1], data[1][2], data[1][3])
			else:
				node.modulate = Color(data[2][0], data[2][1], data[2][2], data[2][3])
				modulate_queue.erase(node)

the error i get ( from tween_node_modulate() )is

Invalid access to property or key ‘modulate’ on a base object of type ‘null instance’.

This is the cutsccene trigger tree


(the colorrect is called overlay)

But it keeps disappearing. Even when i call _ready() from the cutscene trigger area, and look for $Overlay, it throws me an error saying that it doesn’t exist. This error, to be precise

Node not found: “Overlay” (relative to “/root/GameWrapper/SceneTutorial/MailboxCutsceneTrigger”).
<Errore C++> Method/function failed. Returning: nullptr
<Sorgente C++> scene/main/node.cpp:1792 @ get_node()
mailbox_cutscene.gd:41 @ _ready()

Seems like all the pieces are there, how is the MailboxCutsceneTrigger instanced?

Sorry for the late reply, i had some busy days. Anyways this is the whole mailbox trigger code

extends PlayerDetectingArea

var once = true
const middle = Vector2(112, -463)
const end = Vector2(2451, -557)

var overlay

signal dialog_done

var dialog_data = [
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "Yay, I finally made it! That was... less straightforward than I expected."},
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "Oh, I got mail!! Now, what's this?"}
]

var dialog_data_2 = [
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "The Mansion seal.. This looks like a message from the princess! Now, let's see..."}
]

var dialog_data_3= [
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "The Princess is hosting a coronation ceremony!!! Wowie!!! I should totally go pack my things and move to my mansion rooms ASAP!!"},
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "..."},
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "..."},
	{"Name" = "Gio", "PortraitId" = 0, "Text" = "...my house is on the other side of the field..."}
]

func _ready():
	overlay = $Overlay
	
	for child in get_children():
		print(child)

func _input(_ev):
	if Input.is_action_just_pressed("next_text") and player_in_zone and once:
		once = false
		
		BulletManager.get_wrapper().fadeout_music()
		DialogManager.new_dialog(dialog_data, dialog_done, false)
		await dialog_done
		
		$ArtGioReadLetter.visible = true
		CutsceneManager.tween_node_globalpos($ArtGioReadLetter, global_position + middle, 1.5)
		await get_tree().create_timer(3).timeout
		
		DialogManager.new_dialog(dialog_data_2 ,dialog_done, false)
		await dialog_done
		
		CutsceneManager.tween_node_globalpos($ArtGioReadLetter, global_position + end, 0.8)
		CutsceneManager.tween_node_modulate(overlay, Color(212.0/255,232.0/255,251.0/255,1), 0.8)
		await get_tree().create_timer(1).timeout
		$GhostyLetter.global_position = BulletManager.get_player().global_position
		$GhostyLetter/Label.visible_characters = -1
		CutsceneManager.tween_node_modulate($GhostyLetter, Color(1,1,1,1), 1)
		await get_tree().create_timer(2).timeout
		
		BulletManager.get_wrapper().play_audio_global("res://Sound/Voiceover/VOICE_GhostyLetter.mp3", 5)
		await get_tree().create_timer(15).timeout
		CutsceneManager.tween_node_modulate($GhostyLetter/GhostySign, Color(1,1,1,1), 2)
		await get_tree().create_timer(3).timeout
		
		CutsceneManager.tween_node_modulate(overlay, Color(0,0,0,1), 0.8)
		DialogManager.new_dialog(dialog_data_3 ,dialog_done, false)
		await dialog_done

the dialog data variables are just how i implemented the data for my dialog system, also about anything works except when i call CutsceneManager.tween_node_modulate() with overlay as an argument.

In _ready(), i also assign the overlay variable and iterate through the children of the trigger to make sure the overlay is in them, and the overlay is missing there also. Finally, PlayerDetectingArea is a custom class that i made that just basically works like an Area2D except that when the player enters/exites, the boolean variable player_in_zone gets updated as a result

oh my god. oh my god. I’m mortified. I had made a backup of the scene i was working on and i was editing the BACKUP while running the ORIGINAL. So i was making changes that weren’t getting run. Oh my god i’m so sorry

Might be a good time to look into better back up solutions like git for “source control”. These programs let you keep a timeline of your program, easily storing and reverting a day’s work.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.