Describe the project you are working on:
Making a game that makes a lot of use of Control nodes and a few key colors that are used throughout.
Describe the problem or limitation you are having in your project:
In my current project we're using certain colors extensively throughout all our UI to signal things to the player. Green is a positive stat, red is a negative stat, et cetera. I have been trying to set up my project in such a way to easily allow these important colors to be adjustable for players, to aid any player that might have issues differentiating between certain colours. However I have yet to find a way that makes it easy to create such settings.
The main issue I have been having is that colors can be used in a lot of different places (font, stylebox materials, modulation variables) and the only way to adjust all of them, would be to keep track of them in a singular place and adjust the color in all instances through a script. The other way I can think of is to make a screen-wide shader that changes selected colors into others. However that seems a bit extreme for simply wanting to adjust all instances of a single color throughout your UI, and likely a lot heavier on performance too.
Maybe I have missed something, but I don't think there currently is a good way to adjust a specific color through all instances of the project where this color is used (in the same way that a PNG or material can be adjusted).
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
I would like to see a new resource added: the 'Color' resource. This would be a file that is saved and holds the information of a single color. This resource could then be used in any location where a Color input is required, to make a reference to the saved resource. Think of font_color entries, StyleBox Materials for panels, Modulation/Self_Modulation values.
That way, if during development the color needs to be changed, it can be changed in the set-up resource, rather than in every individual scene, manually. The same way that making changes to a PNG or a Scene would update all instances in which that resource is used. These resources could then also be used for (accessibility) settings, such as to allow players to easily adjust the font colors throughout all UI scenes, or to allow players to adjust colors they might have difficulty seeing due to colorblindness. (Think of the green & red I am currently using to indicate positive & negative stats throughout my project).
Essentially I want a resource akin to saving a Stylebox material, but only for a single color, so it can be used and referenced throughout the editor where Color inputs are required.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I hope I have made this clear in my examples and explanation. If required I will make a mock-up, but I think the functionality would be in line with all other resources that can currently be made and used throughout the Godot Engine.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
I haven't found a way to properly adjust Color references throughout a project, and I think this will be used a lot by developers that use Control nodes in their projects, as those are the places that Color inputs are most often needed.
Is there a reason why this should be core and not an add-on in the asset library?:
The use of Color inputs throughout the editor makes me feel like this should be a core part of the engine.
Thank you!
If you are speaking strictly Control nodes, you should define color constants on your main theme and adjust them with user preferences. That鈥檚 how theming is done for the editor, for example. You鈥檇 still need some system-wide signal, probably, to update colors on the fly. You can use a global helper instance for that.
If you need to store a group of related colors to interpolate between, you can use the Gradient resource to achieve this. (Note that you don't have to interpolate between them, but you can. If you don't want to, only use Gradient.interpolate() with an offset where a stop is explicitly defined.)
Worth mentioning that I've previously implemented VectorResource class, so you can take it as a base to create a similar plugin.
The main advantage of using a resource is that you can connect the changed() signal to virtually any update() method within your project. The plugin originated from #397 proposal.
There was a discussion that core types like Vector2, Rect2, Color, etc. could be made possible to use as resources out of the box, so you could also store any core types on disk, not just Color. At least that's my idea behind it.
If you are speaking strictly Control nodes, you should define color constants on your main theme and adjust them with user preferences.
The issue with Themes, as far as I understand them, is that it affects all children as well. So creating a singular main theme would make all labels look the same, which is not what I need. Having said that, perhaps I could use themes on nodes that do not have children, to create a theme with a specific font colour, so adjusting the theme would update these instances Would limit it to node types and visual appearances that are the same, but better than nothing. Thanks for the suggestion!
If you need to store a group of related colors to interpolate between, you can use the Gradient resource to achieve this. (Note that you don't have to interpolate between them, but you can. If you don't want to, only use Gradient.interpolate() with an offset where a stop is explicitly defined.)
Thank you! I'll definitely investigate. As I thought there must be ways to work around my limitation, but to me saving a Color reference as a resource would still be the preferred/logical way to handle my situation. But that might just be my current level of understanding of the engine, or the way I view the issues I'm trying to solve.
Worth mentioning that I've previously implemented VectorResource class, so you can take it as a base to create a similar plugin.
Very interesting! I'll take a look, who knows, maybe I'll attempt to create such a plugin one day. Thank you for the info!
The issue with Themes, as far as I understand them, is that it affects all children as well. So creating a singular main theme would make all labels look the same, which is not what I need.
This is not what I suggest you use a theme for. You can define color constants with themes. Not assign colors for properties of control nodes, but define a set of colors you can then access at will anywhere where this theme is propagated.
Set them on a theme resource by providing names and optional types.
theme.set_color("red_color", "FirstType", Color.red)
theme.set_color("green_color", "FirstType", Color.green)
theme.set_color("blue_color", "SecondType", Color.blue)
Then on any control node below the one that sets this theme you can get those colors and use as you would like.
I've tried using Theme with Sprite (not Control):
# character.gd
extends Sprite
export(Theme) var theme setget set_theme
func set_theme(p_theme):
if theme == p_theme:
return
if is_instance_valid(theme):
theme.disconnect("changed", self, "_on_theme_changed")
theme = p_theme
if is_instance_valid(theme):
theme.connect("changed", self, "_on_theme_changed")
func _on_theme_changed():
modulate = theme.get_color("team", "Character")
# main.gd
extends Node2D
func _ready():
$character.theme.set_color("team", "Character", Color.green)

Saying that it's possible to reuse Theme as a proposed Color resource, even if the documentation suggests that it's used for UI. 馃憖
Test project:
godot_theme_sprite.zip
This is not what I suggest you use a theme for. You can define color constants with themes. Not assign colors for properties of control nodes, but define a set of colors you can then access at will anywhere where this theme is propagated.
Oh interesting! I had no clue themes could be used this way. I have just set one up, and it's a very convenient way to store and access a whole host of colours! Definitely better than setting up a singleton and saving them in there.

The only drawback I see with this method is that (as I understand it) it would require each individual control node that uses one of the saved colours, to also have a script that sets this colour to the correct variable. While this is not the end of the world, it is exactly why I'd hoped a 'Color' resource could be added. Instead of requiring a script to set the Color to the variable, it could be slotted into the Editor UI, where ever a Color Input is required.

_an example of a small part of the UI I'm currently working on, showing all the different nodes/variables that can use a single colour_
As you can see this small part of my project would already require 5 or so scripts, and I expect that throughout the project we will have hundreds of similar instances with other variables/nodes or colours. I fear that will create a lot of overhead, and a messy project, which is part of why I made the initial request.
Having said that, thank you @pycbouh for showing me that Themes can be used this way! I learned something new, and it is probably the best alternative solution I can think of!
That's some cool investigative work @Xrayez ! Thank you for going out of your way to help me out!
With the previous theme explanation, that should get me pretty far in making one central theme with all important colours, so they can easily be changed through settings. 馃憤
I've come up with a VariantResource class in goostengine/goost#30 which allows you to take any Variant compatible type and edit it just like a resource:

So, this is not limited to just Color. This might not necessarily what this proposal wants to achieve (UI?) but this solves the proposal exactly as it says on the tin.
If core developers find this useful needed, I can write a proposal for this. 馃檪
This might not necessarily what this proposal wants to achieve (UI?) but this solves the proposal exactly as it says on the tin.
Yeah, the one part this would be missing is that these resources could be loaded/dragged into any slot of the Editor UI that requests a Color input, such as Modulation variables, Font_Color variables, StyleBox Color variables, etc. Such as seen below:

_Just wanted to reiterate that for clarity, by no means to disregard your amazing work_ @Xrayez
Personally I think the VariantResource addition could be very useful!
Yeah, the one part this would be missing is that these resources could be loaded/dragged into any slot of the Editor UI that requests a Color input, such as Modulation variables, Font_Color variables, StyleBox Color variables, etc.
While it's unlikely and even a bad idea to replace every Color property with a ColorResource property of sorts, it would be entirely possible to convert those resources to Colors on drag'n'drop in the editor. But that would only be a one time thing, and won't provide the desired functionality for auto-updating on value change. Now, why would replacing be a bad idea? Well, the overhead from using Resources in place of a simple type can be one reason.
Well, the overhead from using Resources in place of a simple type can be one reason.
I understand. Perhaps I have been unclear about this, but I definitely wouldn't want every Color property to ONLY be adjustable through a ColorResource. Setting a Color locally is perfectly fine in most scenarios, so there is no reason to change that, and as you pointed out, forcing ColorResources everywhere would be annoying to deal with. I would like to see both a (local) Color and a ColorResource option for these properties.
In my mind there are multiple ways of handling such a feature (not limited to the ones listed below):
A) The Color Picker UI has a small button, which can be clicked, and opens a Filesystem browser to load a ColorResource.
B) The way Stylebox Materials are set up: You can create one locally (without saving them), or you can choose to save them.
Now obviously I have no clue how difficult any of this would be. I just wanted to make sure there is no chance of the proposal being misunderstood, as I fear that I haven't always been very clear in my previous posts.
What about adding a palette to the Theme resource, and replacing the hard coded color values with ids for that palette? It would have to be integrated well into the editor to make it work.
Wasn't there a plugin recently that did something like that?
What about adding a palette to the Theme resource, and replacing the hard coded color values with ids for that palette? It would have to be integrated well into the editor to make it work.
Regarding palette-like behavior, worth mentioning that I've implemented VariantResource previews in goostengine/goost#30:

And no, those are not Textures, but actual Variant values stored in a Resource, but those are indeed ImageTextures generated as previews for Variant::TYPE_COLOR.
This currently only works if VariantResource has Color set as type, but could be extended to generate previews for any type.
What would make this feature even more powerful is suggested drag-n-drop, but not sure how difficult it is to actually implement via modules.
Most helpful comment
I've tried using
ThemewithSprite(notControl):Saying that it's possible to reuse
Themeas a proposedColorresource, even if the documentation suggests that it's used for UI. 馃憖Test project:
godot_theme_sprite.zip