Unable to change the color of a MeshInstance2D with gdscript

Godot Version

Godot_4.2.2-stable

Question

I can’t figure out why the color isn’t changing through my script. the script is attached to the root node and the MeshInstance2D is a child.

I’ve also tried self_modulate and tried placing the command in func _process(delta):.

@onready var baseColor = $MeshInstance2D.modulate

func _init():
	baseColor = Color(255, 0, 0, 255)
  • $MeshInstance2D is a reference to a node ($ is essentially get_node()), while
  • $MeshInstance2D.modulate is a property of a node

Essentially your onready statement as it is, is assigning the current value of $MeshInstance2D.modulate to ‘baseColor’. Then when you change baseColor in _init(), all your doing is updating this arbitrary variable called baseColor, not the MeshInstance2D’s modulate property.

try:

# get the initial color if needed for later, or remove entirely
@onready var baseColor = $MeshInstance2D.modulate 

func _init():
	$MeshInstance2D.modulate = Color(255, 0, 0, 255)


This is the error that I get when I do it like that.

Have you moved or renamed ‘MeshInstance2D’ ?

This implies this node does not exist as a child of the node running this script.


I don’t think I’ve changed anything.

Oh, move it into _ready()
(should wait for all children to be setup while I think init is firing before)

As this is now chosen as the solution I have updated to make it abundantly clear what is happening in the OP.

Essentially there were two issues:

  1. You can’t directly reference basic types in GDscript, only Objects (not their properties), so
    @onready var baseColor = $MeshInstance2D makes baseColor a reference to the node,
    @onready var baseColor = $MeshInstance2D.modulate is direct assignment, making baseColor the value of modulate.

  2. Accessing child properties can’t be done in _init()

This is shown in the testable code below:

extends Node2D

@onready var baseColor = $MeshInstance2D.modulate

func _init():
	print("Init : baseColor:" + str(baseColor)) # this will print <null> as at this point the @onready has not fired.
	baseColor = Color(255, 0, 0, 255) # we then overwrite baseColor (which is not an object's property), noting this is in the HDR range now
	print("Init : baseColor:" + str(baseColor)) # then this will now print the updated baseColor
	
	# All of the below will fail, as the MeshInstance2D child is not setup yet. #Uncomment to test
	#print("Init : MeshInstance Modulate:" + str($MeshInstance2D.modulate))
	#$MeshInstance2D.modulate = baseColor
	#print("Init : MeshInstance Modulate 2:" + str($MeshInstance2D.modulate))
	
func _ready() -> void:
	print("Ready : baseColor:" + str(baseColor)) # this will print MeshInstance2D's original modulate property as the @onready assignment has copied this value to the vbariable BaseColor
	baseColor = Color(255, 0, 0, 255) # we then overwrite baseColor (which is not an object's property), noting this is in the HDR range now
	print("Ready : baseColor:" + str(baseColor)) # then this will now print the updated baseColor variable
	
	print("Ready: MeshInstance Modulate (from changing baseColor):" + str($MeshInstance2D.modulate)) # this will still print the original MeshInstance2D modulate proprty as it is unchanged
	$MeshInstance2D.modulate = baseColor # this changes it
	print("Ready: MeshInstance Modulate (from assigning to property):" + str($MeshInstance2D.modulate))  # this will now print the updated MeshInstance2D modulate property

Which, assuming you started with a Blue modulate like I did, should output this:

image

And if you uncomment the block in _init() I commented out:

image

Re. later comments, the Color constructor is not clamped to 0-1 (HDR allows for higher values) so is not the cause of the error. As such this would still produce a Red MeshInstance2D, though turning on HDR/Glow will likely result in unexpected results.

1 Like

Color has no constructor that takes RGBA values other than 0 to 1 (float)
Try using Color(1, 0,0,1)
Documentation on the constructors.

like @sancho2 said, or you can just Color8(255,0,0,255)
Color8