Back in 2019, I had a hex map project that I was initially writing in GDScript, however, GDScript got to be too slow when getting the tiles to follow the camera. I ended up having to rewrite the entire project in C++ because I couldn't figure out how to isolate the code for wrapping the tiles. A few years pass, I'm trying the project again and I'm now to the point where I'd need to get the tiles to wrap around the camera's X position. GDExtension operates differently than GDNative, I would assume. How should I approach this problem? I know we need to get the width of the map by multiplying the width of a HexTile by the number of columns. Once we have the map width, we need to calculate a float of how many mapWidths each tile is from the camera. If the tile is more than 0.5 mapWidths from the camera, the tile should jump to the other side of the map to follow the camera. I'm wanting to write only the code for placing the HexTile in accordance with the camera in C++, instead of the entire game this time.
extends Node3D
var hexTilePrefab: PackedScene = preload("res://Scenes/HexTile.tscn")
var mapSize: Vector2 = Vector2(48, 12)
@export var camera: Node3D = null
var hexTileWidth: float = sqrt(3)
var hexTileArray = [[]]
func _ready():
generateHexMap()
func _process(delta):
for q in range(-mapSize.x, mapSize.x + 1):
for r in range(-mapSize.y, mapSize.y + 1):
checkAndWrapTile(hexTileArray[q][r])
func generateHexMap():
# Clear the existing array in case this function is called again
hexTileArray.clear()
for q in range(-mapSize.x, mapSize.x + 1):
var columnArray: Array = [] # Create an array for each column
for r in range(-mapSize.y, mapSize.y + 1):
var hexTile = hexTilePrefab.instantiate()
add_child(hexTile)
hexTile.place_tile(q, r)
checkAndWrapTile(hexTile)
# Add the hexTile reference to the array for this column
columnArray.append(hexTile)
# Add the column array to the hexTileArray
hexTileArray.append(columnArray)
func checkAndWrapTile(hexTile):
# Check the distance between the tile and the camera in world coordinates (X-axis only)
var tilePosition = hexTile.transform.origin
var cameraPosition = camera.transform.origin
var distanceX = abs(tilePosition.x - cameraPosition.x)
# Calculate how many map widths away the tile is from the camera along the X-axis
var mapWidthsAwayX = distanceX / (hexTileWidth * mapSize.x)
# If the tile is more than 0.5 map widths away from the camera along the X-axis, wrap it to the other side
if mapWidthsAwayX > 0.5:
# Calculate the new position of the tile to wrap it along the X-axis
var wrappedPosition = tilePosition
if tilePosition.x - cameraPosition.x > 0:
wrappedPosition.x -= hexTileWidth * mapSize.x
else:
wrappedPosition.x += hexTileWidth * mapSize.x
# Set the new position for the tile
hexTile.transform.origin.x = wrappedPosition.x
extends Node3D
var axial: Vector2
var cube: Vector3
var worldPosition: Vector3
func axialToCube(axial: Vector2) -> Vector3:
var x = axial.x
var z = axial.y
var y = -x - z
return Vector3(x, y, z)
func cubeToWorld(cube: Vector3) -> Vector3:
var hexSize = 1.0
var x = hexSize * sqrt(3) * (cube.x + cube.z / 2)
var y = 0
var z = hexSize * 3/2 * cube.z
return Vector3(x, y, z)
func place_tile(q, r):
axial = Vector2(q, r)
cube = axialToCube(axial)
worldPosition = cubeToWorld(cube)
transform.origin = worldPosition