#Material Coloring & Saving

1 messages · Page 1 of 1 (latest)

worn mango
#

I am trying to make the white part of this blender model be able to change color, but i tried searching around and don't see a answer to do it clearly, basically i wanna be able to change the color of Eye Color (copy), and Changable color, but found no way to do it, every way i found so far results in a error, for just wanting to change a material... i also wonder if it is possible to make it so that the colors are only unique to this player model since all models for my game use the same materials, but ofc i want to be able to make them be diffrent colors at the same time, not sure how to do that yet

civic meteor
#

It looks like you're trying to reference the material file in the res:// file system, but I think you should look at the MeshInstance3D or whatever you use to show the model. In that node, you can first look at the Mesh. Each surface in the Mesh can have its own material, but changing it here will affect all instances of the mesh (though it might be possible to get around by making it local to the scene). However, the MeshInstance3D also has Surface Material Override, where you can override a material for only this instance, if that's what you want.

worn mango
#

then yeah, Surface Material Override

#

idk how to do that, though i wonder how i'd only affect the white part here not the black as well

#

or how'd i even go about affecting the surface material override

civic meteor
#

Since the white part appears to be Surface 0, so if you override the "0" material then it should only affect that. Then how to modify that in code, either refer to the manual or hover the property in the editor to get its name. I.e. first find the property for "Surface Material Override" in MeshInstance3D (which happens to be surface_material_override :)), then get material 0 from that. Once you have the material reference, you might have to cast it to StandardMaterial3D to access its albedo property

worn mango
#

oh, alr

worn mango
#

where could i find the documentation on this?

worn mango
#

think i almost got it now, since it isn't crashing but also isn't really changing

#

all it is doing so far is apperently changing the color to black

civic meteor
#

Have you double checked that the variable "color" has the correct value when it comes to your function

#

Can't test anything right now but I think your code looks about right

worn mango
#

it does appear to seem working, but it doesn't seem to be rendering it correctly?

civic meteor
#

Just a minor thing, you're supposed to only create a new material for the surface override once, for example in _ready, after that you modify the albedo of the existing override material

worn mango
#

ah, alr

civic meteor
#

I don't think that's the reason it isn't working for you though.. if you haven't been able to solve it, perhaps you could zip your project and upload it here, and I can take a look at it tonight when I'm home from work

worn mango
#

that could also be why

#

also, alr

#

nvm, that was not the reason

#

i've tried some things and it didn't seem to work, so yeah i'll just upload it here since not much has been done yet with my game, but since it is too large for discord, i'll just google drive it

#

these should be the two scenes you should look at later, since the issue can be seen between these two

#

also yeah, i tried looking at documentation and doesn't really appear to be documented, for what i wanna do

#

which the only things i wanna affect is the white parts of the character, aka eyes, and the outer white

worn mango
#

and please ignore the eyes that say, > boost or < boost, since those should just stay black

worn mango
#

let me know if you figure out what appears to be wrong in the rendering

civic meteor
#

Will do, but I won't be home from work until 3-4 hours from now

worn mango
#

alr

civic meteor
#

large project, looking at it now 🙂

#

I tried adding this to Dash.gd

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("ui_select"):
        colChange(Color.RED)

and the frame turned red when I pressed space, so it looks like it's working

#

The material you have assigned to the Mesh surface 0 (i.e. not the override you're setting runtime) has so strong emission so its albedo_color is not visible at all.

#

The StandardMaterial3D you create for the override doesn't have emission on, which is why changing its albedo_color works.

#

Since you set the mesh "local to scene", I think you don't need to bother with material override, and you can just modify the material on the Mesh itself. E.g. change the function to:

func colChange(color):
    var material := square_backing.mesh.surface_get_material(0) as StandardMaterial3D
    material.emission = Color(color)

This works for me.

#

Now, if this still makes all character change the color when you try to change it for one, then try duplicating the material for example like this:

func _ready():
    BoostBar.visible = false
    var orig_material = square_backing.mesh.surface_get_material(0)
    square_backing.set_surface_override_material(0, orig_material.duplicate())

func colChange(color):
    var material := square_backing.get_surface_override_material(0) as StandardMaterial3D
    material.emission = Color(color)

But if the previous colChange just works, then this is unnecessary.

worn mango
#

whelp, a new issue arises... since i wanna allow you to save a color to be your preferred color between instances, but it doesn't seem like you can save a color?

worn mango
worn mango
#

but yeah, thanks again

#

I'll probably try this color thing i wanted to add another time

#

of the saving of it

civic meteor
worn mango
#

i was confused on that due to the fact, you can create a var normally with a color code, but can't seem to load one easily

#

well, i took a look at the documentation, and seems like i need to use variants, but idk how since here i did variant it

#

Material Coloring & Saving

#

so yeah, i am just confused on how to actually load the color data now

civic meteor
#

Yea there seems to be a lot of confusion here 🙂 Let's try to sort out basic variable usage first.. If you create a variable "preferred_color" it becomes something like a container which can hold a single color value.

When you use an assignment operation you store a new color value in the variable. E.g. preferred_color = Color.BLUE puts the color BLUE in it.

When you use a variable without an assignment, you get the current value out of it. E.g. print(preferred_color) is equivalent to print(Color.BLUE) if that is still the value saved there.

What I'm getting to is that Variant.get_var(preferred_color : true) is the same as writing Variant.get_var(Color.BLUE : true) is wrong in so many ways, and not valid code at all.

Variant.get_var would require the class Variant to have a static method called "get_var", which it does not.

FileAccess has a "open" static method, which is why FileAccess.open(...) is valid code.

FileAccess also has a "get_var" method, but it is not static so you need a FileAccess instance to call it on, which I think you had in your first attempt.

The "(x : y)" is something you use when you create new functions, to specify the type of a parameter. E.g. func do_stuff(preferred_color : Color): means that your function named "do_stuff" takes one argument, which must be of the type Color.

#

Looking again at the manual page for FileAccess.get_var you can see that it takes one parameter, which is a boolean. However, since it has a default value (false) you can also call get_var without parameters. "Variant" here is the type of the return value from this function, but I suppose it's a bit confusing that the manual puts it on the left (like in C++, which Godot uses internally) while you put it on the right in GDScript.

#

I'm guessing your intention was to "get the value for preferred_color from the file", but FileAccess does not work like that. To begin with, when you did file.store_var(preferred_color) it is equivalent to file.store_var(Color.BLUE) if that is the current value being held in the variable. I.e. "store_var" does not have any idea about where that value came from, so it does not store the name of your variable or something like that. Likewise, "get_var" will just get the next value from the file, and it's up to you to put it in the right variable.

worn mango
#

i see

#

yup, pretty much

#

which i basically made it save the variable, after you change the color, and if you wanna save it, it would send that color to another variable to be changed, then saved, and then i try pulling back up that bit of saved color, which then gets set back to the variable coloring, to set the colors of the rest

#

which it appears to get stuck at trying to load that bit of data

#

and this is the other side of the code, which actually sets color

#

which i basically saved it at this

#

do i need to turn the color into a string before saving it?

worn mango
#

nope, appeared to not be it

#

why is it trying to convert to a bool this way?

worn mango
#

i got it to the type of value i want now, but i do see now that it appears to just be saving it as "."

worn mango
#

finally, fixed it

civic meteor
worn mango
#

yeah, sorry took a moment to process what you meant

civic meteor
#

I think preferred_color = file.get_var() as Color could work as well. That tries to convert the Variant to a Color.

#

No worries, it can take a bit of getting used to "thinking in code" 🙂 But I really recommend trying to understand what the manual says, because that'll help you solve other problems in the future

worn mango
#

yeah, still in the learning stage of things, but i do at least understand enough to code some things from what i understand

civic meteor
#

Never used FileAccess, but if it's possible to save a dictionary, then that might be easier if you want to save multiple things in the same file. E.g. something like file.store_var({"preferred_color": preferred_color})