Set each point color for Line2D

Godot Version

Godot Engine v4.3

Question

Hello
How can I set each point color in my PackedVector2Array?
In the end I will have a vector with points each of different color

PackedVector2Array.add_point(Vector2(1,1), Color.RED)
PackedVector2Array.add_point(Vector2(2,2), Color.BLUE)
PackedVector2Array.add_point(Vector2(3,3), Color.GREEN)
for point in PackedVector2Array(Line2d):
     print(point.position)
     print(point.color)

The above code is just a mockup.
The image is just to visualize what I am trying to achieve
image

Thank you in advance.

A PackedVector2Array, by definition, only holds Vector2 values - you can’t really add extra stuff. You could keep a PackedColorArray separately, and make sure to always update the two arrays at the same time and in the same way, so you know that the point and the color that are at the same index in those arrays, are associated with each other.

Alternatively, you can create a class that holds a point and a color, and make a typed array of those. That won’t be quite as efficient as a PackedVector2Array, but perhaps good enough? I don’t know your use case…

Path2D does not have a visual component, I assume you mean a Line2D. Line2D does have a gradient parameter you could use to produce colors, though it’s not so easy to match the points with the gradient’s offsets. You would have to calculate the distance to each point and normalize it by the total distances. Here’s a pretty rigid example, requiring your Line2D to have a gradient and at least one point to start.

extends Line2D

func add_color_point(pos: Vector2, col: Color) -> void:
	add_point(pos)
	gradient.add_point(1.0, col)
	await get_tree().process_frame
	calculate_gradients()

func calculate_gradients() -> void:
	var total: float = 0
	var distances: Array[float] = [0.0]
	# calculate point positions/lengths
	for i in range(1, points.size()):
		var distance := points[i-1].distance_to(points[i])
		distances.append(distance)
		total += distance

	# replace gradient offsets
	var this_distance: float = 0.0
	for i in range(gradient.offsets.size()):
		this_distance += distances[i]
		gradient.offsets[i] = this_distance / total

The use case is that I have a Line2d with default color, and when the line croses an object I want that line cross to be red and after return to the default color, when I set the default_color property it changes the color for the whole line at that moment, but I only need for the collision section

You might be able to adapt the gradient to be more solid, by adding two points for every color. Could you get away with making a separate Line2D for this collision check and only changing that one’s default_color?

I have not used gradient but will try, I also think that I will just create an array of Vector objects, where each object will hold the section of the line, thus making them seperate and will change the property of the default_color to which I need for each of them

1 Like

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