I'm not certain what the issue is, but what is with this line? I'm suspicious of it.
add_child(self)
Why are you childing the node to itself?
I'm not certain what the issue is, but what is with this line? I'm suspicious of it.
add_child(self)
Why are you childing the node to itself?
Very strange, your code works perfectly for me. At 100:
At 75:
What version of Godot are you using? Is your hexagon childed to anything that could be clipping its top-left?
award No, not really anything fancy here.
I am running Godot 4.1.1
For reference I have attached the project here:
Just wondering: for visual reference in the editor, I have also drawn a polygon shape for that Scene but I guess that gets overwritten by
var array = PackedVector2Array([pt0, pt1, pt2, pt3, pt4, pt5, pt0])
self.polygon = array
Below the "dummy" hexagon in the 2D View of my Tile scene:
Ah I'm sorry that I misunderstood your issue! The hexagon isn't drawing properly because the texture is a hexagon with transparency, so part of it is just drawing transparency. Your only issue is not actually scaling the texture. You can do
var referenceLength = 100.0
var edgeLength = 75.0
and then later
var scale = referenceLength / edgeLength
self.set_texture_scale(Vector2(scale, scale))
max_godot When working on this use a dummy texture without transparency with just a hex silhouette. That way you'll immediately see any mismatches.
If I understand the problem correctly, texture scale factor should be (2.0 * edgeLength) / textureWidth
, given that the hex in the texture occupies maximum space.
Ah I misunderstood again! I am sorry
@xyz you have it inverted. texture_scale scales the UVs, not the texture itself. You're right about texture width though.
@max_godot I thought your initial picture was drawing correctly. I realize now that one was also incorrectly scaling.
There are a few lines you need to add / change.
var pt0 = Vector2(edgeLength*0.5,0)
When you construct your vertices, it's easiest if you have your leftmost point at x=0. Replacing pt0 with the above line gives that result.
var scale_x = float(texture.get_width()) / (edgeLength * 2)
var scale_y = float(texture.get_height()) / (height)
self.set_texture_scale(Vector2(scale_x, scale_y))
Here we are scaling the width and height of texture_scale using the texture width and height while keeping the aspect ratio of your hexagon polygon.
Something else I learned: CanvasItem UVs scale per-pixel rather than 0 to 1. I tried at first just setting a UV array but it was completely off because of that.
Ideally. It's worth understanding the reason why. When you set the points in a Polygon2D, it (apparently) gives them equivalent UV coordinates, which are in relation to the position
of the Polygon2D node. You can think of the node's position as the pivot for all the points. It is at (0,0) for them. So a point at (100,100) will have a UV of (100,100).
The UVs of the points line up to pixels on the texture. So if your leftmost UV is at (100, 0), then it will only start after the 100th horizontal pixel of the image. Likewise a topmost UV of (0, 100) would only start after the 100th vertical pixel of the image, from top to bottom.
You don't have to line up the top or the left. You could manually set the UVs per point via Polygon2D.uv
, or you could adjust Polygon2D.texture_offset
to compensate for your "top left". But the easiest way when constructing a new polygon is to simply make your points line up with the top and the left.