What's the code to set color?

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

Another frustrated noob here.

The only tutorials I can find relate to Godot 3, so now all out of date. Don’t tell me to RTFM either, that thing’s got me going around in circles!

Why can’t the code just be this?

  • on a MeshInstance sound sensible -
    node_name_as_per_tree.set_albedo(color(those red, green, blue, numbers))

MeshInstance2D or MeshInstance3D?

jgodfrey | 2023-05-26 18:51

Sorry, should have said, 3D. My game’s only going to work if it’s 3D.

Curiously99 | 2023-05-26 21:10

:bust_in_silhouette: Reply From: Cogan
MeshInstance3D.mesh.material.albedo_color = color

I’ve created a scene to demonstrate this.

Sorry Cogan, I downloaded it, unzipped it, and tried importing it - twice, but nothing. I am on a crappy old Chromebook, although that shouldn’t make a difference, right?

Curiously99 | 2023-05-26 21:30

Ok then I’ll show you all the necessary things.

First Add a StandardMaterial3D as the material property in your mesh.
Image of Adding StandardMaterial3D as material

then, if you’re changing the color from a script attatched to the MeshInstance3D:

mesh.material.albedo_color = color

If you’re changing it from another object:

MeshInstance3D.mesh.material.albedo_color = color

Cogan | 2023-05-26 22:24

Definitely closer, but a couple of things.

Firstly, if I run colorpicker without any script, it puts the color console within the game window itself. That’s not what I want long-term. What I’m after is an expression to assign color that I can then use in a broader ‘if something is touching then change color’ statement.

Secondly, and sorry about needing to be spoonfed this, but now the color element itself is causing problems. The closest I’ve manged is this:

The node tree is: StaticBody3D>MeshInstance3D>CanvasLayer>ColorPicker
extends ColorPicker
const BLUE = Color(0, 0, 1, 1)
func _ready() → void:

  • indent - MeshInstance3D.mesh.material.albedo_color = BLUE

But ‘invalid get index ‘mesh’ on base MeshInstance3D’, and so the game window was just empty grey. The crazy thing is, on the viewport, the damn thing turned blue!!

(I found ‘draw_mesh()’ in the docs and thought I had it for a moment, but it looks like it’s only available in 2D.)

Curiously99 | 2023-05-27 05:54

OK, so forget about it turning blue in the viewport, I can’t seem to replicate that now.

Curiously99 | 2023-05-27 06:11

Ok then I’ll try to explain this better. The color picker and canvas layer nodes are not necessary. This function can be called from any script, including a script attached to the mesh instance itself.

If it’s being called by a script attached to the mesh instance it’ll be really easy. you just type this

const COLOR = Color(0, 0, 1, 1)
mesh.material.albedo_color = COLOR

In this case (remember this is only if it’s a script attached to the MeshInstance3D that is changing color) COLOR represents a color. It could also be a variable or even just a hard coded value. Mesh is the value of the mesh variable in the mesh instance 3D node. This will give you the mesh that is assigned to the mesh instance 3D node. The period means that it’s a value of the given object, so material means the material of the mesh of the MeshInstance3D that the script is attached to. If the material is a StandardMaterial3D, it will have the property albedo_color. The second line sets that property to color. Also I’m sorry for the wall of text, I’m just really trying to help you understand this.

If you’re calling the function from a script attatched to a different object, it’s gonna work almost exactly the same, but first you’ll need a variable that defines the MeshInstance3D (that has the mesh that has the material that has the albedo_color property) so if you’re calling from a separate object it would look something like this (mesh_instance is a variable that can have a different name if you want as long as it’s a mesh instance with a mesh with a material with an albedo_color property)

const COLOR = Color(0, 0, 1, 1)
mesh_instance.mesh.material.albedo_color = COLOR

Cogan | 2023-05-27 06:38

I see how the ‘…instance.mesh.material.albedo…’ path essentially mirrors the location of albedo in the user interface, that’s good to know. Probably works in lots of other contexts.

Here’s the screenshot:

It’s basically showing the same error I’ve been describing, is it saying that the color value it’s returning is null?

Curiously99 | 2023-05-27 09:47

Your code looks fine. Could I see the MeshInstance3D in the inspector with the mesh clicked like in that one screenshot I sent? Not the script the node.

Cogan | 2023-05-27 19:12

Thanks for getting back to me Cogan, this must be trying your patience.

So yes, asking for that screenshot made me realise, I hadn’t actually added a standard material!. You can’t code something in the script which you haven’t enabled in the inspector, right?

So now the code is running without any bugs at all, and the game window is showing my static body. But the cube won’t change color! It just stays black!!

Viewport & inspector:

Game window:

Really not sure where we go from here…

Curiously99 | 2023-05-27 20:12

… but the color’s not changing from the inspector either!

I need to experiment with the inspector. I hadn’t seen the material color, I’d been using the surface material override. That must be interferring with the material color.

Leave this with me, I’m going to figure this out.

Curiously99 | 2023-05-28 05:38

It looked like you didn’t have any lighting nodes in the screenshot you sent. Try adding lighting and tell me if it works then.

edit: Also scripts don’t run in the viewport unless they have “@tool” on the first line (even before the line that says “extends SomeObject”

Also also, unless you wanna change the color during the game, you can just change the albedo color in the material settings without code.

Cogan | 2023-05-28 05:42

Cogan, I’ve done it!

Here’s the celebratory screen shot:
(Impressive right?)

I did have lighting nodes, they were just hidden away on other nodes. Good to know about the @tool, I did always wonder about how people viewed updates within the Viewport.

The main thing is, I had been using surface_material_override, not mesh.material in the inspector. The inspector settings were conflicting with my code.

Cogan, I’ve learned from this exchange, I really appreciate your help.

Curiously99 | 2023-05-28 10:45

Nice! Glad I could help.

Cogan | 2023-05-28 11:11