I’ve created a 3D hexagonal grid for a turn-based strategy game (without using the builtin tilemap) in the shape of a rhombus. Its node tree looks like this:
World (Spatial)
|—-HexGrid (Spatial)
|—Camera
|—HexTile_0_0 (StaticBody) (added at runtime)
|—HexTile_0_1 (StaticBody) (added at runtime)
. . .
Each HexTile has an Armature -> Skeleton -> MeshInstance, a TextureRect -> RichTextLabel, and a CollisionShape as children
The problem is that I want to have roughly 400×400 tiles in my grid, and it is generating much too slowly (>10 minutes). (The tiles don’t even have any properties or functionality yet, I’m talking about simply instantiating them all). I know there are games with large playing grids that generate their maps quickly, so I’m worried that I’m organizing my project incorrectly, or doing something else badly wrong. Does anyone have advice or resources about how to make a performant large hex grid in Godot? Does Godot’s builtin TileMap node give a substantial performance improvement?
EDIT: Here is the script I’ve attached to my HexGrid node. Godot’s profiling indicates that most of the time usage happens in the _ready() function of this script. The intent is to create the grid of hexagons, give them random heights, then tell each of them who their neighbors are, and use the attached armatures to “tilt” the hexagon meshes to connect with their neighbors.
~~~~ tool extends Spatial
var size := 1.0 var w := sqrt(3.0)size var h := 2size
var height_step = 0.1 var cliff_threshold = 0.4 var cliff_min_height = 0.4
export var hexagonal := false export var wraparound := true export var map_w := 24 export var map_h := 16 export var noise : OpenSimplexNoise = OpenSimplexNoise.new()
onready var hex = preload(“HexTileNew.tscn”) onready var camera = $CameraBase
func hex_coord_round(coords:Vector2): var a0 = round(coords.x) var b0 = round(coords.y) var c0 = round(-coords.x-coords.y)
var a_diff = abs(a0-coords.x) var b_diff = abs(b0-coords.y) var c_diff = abs(c0+coords.x+coords.y) if a_diff > b_diff and a_diff > c_diff: a0 = -b0 - c0 elif b_diff > c_diff: b0 = -a0 - c0 return Vector2(a0,b0)
func pos_to_hex_coords(pos:Vector2): var x = pos.x var y = pos.y return Vector2((1.0/w)x-(2.0/(3.0h))y,(4.0/(3.0h))*y)
func hex_coords_to_pos(hex_coords:Vector2): var a = hex_coords.x var b = hex_coords.y return Vector2(w(a+0.5b),0.75hb)
func _ready(): camera.w_limit = wmap_w camera.h_limit = 0.75h*map_h camera.wrap_x = wraparound
noise.period = 16 if not hexagonal: for a in range(-map_w,map_w+1): for b in range(-map_h,map_h+1): var pos = Vector2(w*(a+0.5*b),0.75*h*b) var height_noise if wraparound: height_noise = Functions.loop_noise_2dv_horizontal(pos,w*map_w,noise,Vector2(10000.0,10000.0)) else: height_noise = noise.get_noise_2dv(pos) var height = stepify(2.0*height_noise, height_step) + height_step/2.0 var hexInstance : Spatial = hex.instance() add_child(hexInstance) hexInstance.global_transform.origin = Vector3(pos.x,0,pos.y) hexInstance.hex_coords = Vector2(a,b) hexInstance.set_bone_height(0,height) var label = hexInstance.get_node("TextureRect/RichTextLabel") label.text = str(a)+" , "+str(b)+"\n"+str(height) hexInstance.name = "Hex_"+str(a)+"_"+str(b) print_debug("Created hex at "+str(a)+", "+str(b)) for a in range(-map_w,map_w+1): for b in range(-map_h,map_h+1): var hexTile = get_hex_at_coords(Vector2(a,b)) var neighbor_coords = get_neighbor_coords(Vector2(a,b)) if wraparound: for i in range(6): if neighbor_coords[i].x == -map_w - 1: neighbor_coords[i].x = map_w elif neighbor_coords[i].x == map_w + 1: neighbor_coords[i].x = -map_w for i in range(6): hexTile.neighbors[i] = get_hex_at_coords(neighbor_coords[i]) for i in range(6): if hexTile.neighbors[i] != null: var neighbor_height = hexTile.neighbors[i].current_height[0] var height = hexTile.current_height[0] var diff = neighbor_height-height var modified_neighbor_height if diff < -cliff_threshold: modified_neighbor_height = height - 0.5*(abs(diff)-cliff_min_height) elif diff > cliff_threshold: modified_neighbor_height = height + 0.5*(abs(diff)-cliff_min_height) else: modified_neighbor_height = neighbor_height hexTile.set_bone_height(i+1,modified_neighbor_height) else: hexTile.set_bone_height(i+1,hexTile.current_height[0]) #pass #print_debug("Modified hex at "+str(a)+", "+str(b))
func get_neighbor_coords(hex_coords:Vector2): return [ hex_coords+Vector2(1,0), hex_coords+Vector2(-1,0), hex_coords+Vector2(1,-1), hex_coords+Vector2(0,-1), hex_coords+Vector2(-1,1), hex_coords+Vector2(0,1) ]
func gethex_at_coords(hex_coords:Vector2): return get_node_or_null(“Hex“+str(hexcoords.x)+”“+str(hex_coords.y)) ~~~~
submitted by /u/bluegreen1024 to r/godot
[link] [comments]
More Stories
Will County, Illinois 1864 Map – May 20, 2023 at 04:14AM
This kid on Google Map trying to get by – April 27, 2023 at 05:05PM
World of Hyatt: Complete list of all-inclusive properties in Europe (with map) – April 27, 2023 at 04:57PM