Not sure how to use gradients in TextureRect

Godot Version

4.4.stable

Question

I am trying to change the background of my game based on the time of the day. I was thinking of using the “hr_counter” variable to dictate what color to display on the screen based on the hour of the day. The value of the “hr_counter” variable would start at zero (for midnight) and display the color on the very left of the gradient, then switches to every color to the right of it indicated by the markers shown below at different hours, then becomes white at noon, then goes backwards as the hours past noon progresses. Below is the gradient I want to use, which I found online:

The problem is, I have no idea what code to use to display the associated colors as an overlay on my game. I’m also not sure how to make the TextureRect opaque, which would allow me to see the game itself.

Okay, so you want the texturerect to be only one color at once, but the color changes throughout the day? You could use a CanvasModulate. Or a ColorRect with modulate.a (alpha) set to something less than 1 that goes over the entire screen. I assume when you say opaque (cannot be seen through), you mean translucent (partially transparent)? You don’t need to have the actual gradient on a TextureRect to accomplish this.

Modulation works like a multiply layer in a drawing software. If you want a different effect, you could look into Light2D or shaders.

Gotcha. I added a CanvasModulate in the node tree, as follows:

This is what I have in the Canvasmodulate node:

All of my code is in the script attached to the “Time_Function” node. I added the following lines of code:
@onready var canvas_modulate: CanvasModulate = $CanvasModulate

and

canvas_modulate.color = canvas_modulate.gradient.sample()

  • This was added in my func _process(_delta), where all of the code that determines time, hour, month, and day are located.

Now, my problem is that I don’t know what code to write to display the color on screen and make it change throughout the day.

The sample function takes in an offset variable, which should be dependant on the time elapsed in the day.

This is how I have my timer code currently (allows for pausing and accelerating time as well):

extends Node

var minutes: int = 0
var hours: int = 0
var days: int = 1

var is_paused: bool = false
var minute_counter: bool = false
var hr_counter: bool = false
var day_counter: bool = false

var dict_count: int = 0
var month_dictionary = {
	0: "January",
	1: "February",
	2: "March",
	3: "April",
	4: "May",
	5: "June",
	6: "July",
	7: "August",
	8: "September",
	9: "October",
	10: "November",
	11: "December"	
	}
	
var month_length = {
	0: 31,
	1: 28,
	2: 31,
	3: 30,
	4: 31,
	5: 30,
	6: 31,
	7: 31,
	8: 30,
	9: 31,
	10: 30,
	11: 31
}

@onready var date_display: Label = $CanvasLayer/date_display
@onready var time_display: Label = $CanvasLayer/time_display
@onready var canvas_modulate: CanvasModulate = $CanvasModulate

func _process(_delta):
	canvas_modulate.color = canvas_modulate.gradient.sample(hours)
	
	if is_paused == true:
		return
		
	if minute_counter == true:
		minutes += 1
	
	if hr_counter == true:
		hours += 1
	
	if day_counter == true:
		days += 1
	
	if minutes > 59:
		hours += 1
		minutes = minutes - 60
	
	if hours > 23:
		days += 1
		hours = hours - 24
	
	if days > month_length[dict_count]:
		days = days - month_length[dict_count]
		dict_count += 1
	
	if dict_count > 11:
		dict_count = dict_count - 12
	
	date_and_time_display()
	
func date_and_time_display():
	date_display.text = "Current time - " + str(month_dictionary[dict_count]) + " " + str(days)
	time_display.text = "%02d:%02d" % [hours, minutes]

func _on_pause_pressed():
	is_paused = true

func _on_1x_speed_pressed():
	minute_counter = true
	hr_counter = false
	day_counter = false
	is_paused = false
	
func _on_2x_speed_pressed():
	minute_counter = false
	hr_counter = true
	day_counter = false
	is_paused = false

func _on_3x_speed_pressed():
	minute_counter = false
	hr_counter = false
	day_counter = true
	is_paused = false

I’m assuming just putting in hours to the sample function doesn’t work? I’m not sure exactly what number should go into the sample function, but it might be a number between 0 and 1? You should divide hours by 24 and put it into the sample function.

Hi,

Yes, putting the hours variable didn’t work. I tried to divided it by 24, but that didn’t work either. I got the following error message:

image

So it seems I’m using the wrong function, but I don’t know what the right function is.

gradient is a GradientTexture1D and not an actual Gradient, you need gradient.gradient.

Awesome, that worked! Thank you!

1 Like

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