79 lines
2.1 KiB
Plaintext
79 lines
2.1 KiB
Plaintext
[gd_scene format=3 uid="uid://difktsmww6qlh"]
|
|
|
|
[sub_resource type="GDScript" id="GDScript_mjcif"]
|
|
resource_name = "AGUIContainer"
|
|
script/source = "@tool
|
|
extends Node3D
|
|
|
|
## Number of items per row (X-axis)
|
|
@export var columns: int = 2:
|
|
set(value):
|
|
columns = max(1, value)
|
|
_sort_3d_children()
|
|
|
|
## Number of rows per layer (Z-axis)
|
|
@export var rows: int = 2:
|
|
set(value):
|
|
rows = max(1, value)
|
|
_sort_3d_children()
|
|
|
|
## Spacing between 3D objects in units
|
|
@export var cell_size: Vector3 = Vector3(2.0, 2.0, 2.0):
|
|
set(value):
|
|
cell_size = value
|
|
_sort_3d_children()
|
|
|
|
func _ready():
|
|
_sort_3d_children()
|
|
child_order_changed.connect(_sort_3d_children)
|
|
|
|
func _sort_3d_children():
|
|
# 1. First pass: Gather valid Node3D children
|
|
var 3d_children: Array[Node3D] = []
|
|
for child in get_children():
|
|
if child is Node3D:
|
|
3d_children.append(child)
|
|
|
|
var total_items = 3d_children.size()
|
|
if total_items == 0:
|
|
return
|
|
|
|
var items_per_layer = columns * rows
|
|
|
|
# 2. Calculate the actual dimensions used by the current number of items
|
|
# We use max(1, ...) to avoid multiplying by 0 if there's only 1 item
|
|
var active_columns = min(total_items, columns)
|
|
var active_rows = min(ceil(float(total_items) / columns), rows)
|
|
var active_layers = ceil(float(total_items) / items_per_layer)
|
|
|
|
# 3. Calculate the center offset
|
|
# (Total dimensions - 1) * cell_size / 2 gives us the exact mid-point
|
|
var offset = Vector3(
|
|
(active_columns - 1) * cell_size.x,
|
|
(active_layers - 1) * cell_size.y,
|
|
(active_rows - 1) * cell_size.z
|
|
) * 0.5
|
|
|
|
# 4. Second pass: Position children and subtract the offset
|
|
for index in range(total_items):
|
|
var layer = index / items_per_layer
|
|
var index_in_layer = index % items_per_layer
|
|
var col = index_in_layer % columns
|
|
var row = index_in_layer / columns
|
|
|
|
var local_pos = Vector3(
|
|
col * cell_size.x,
|
|
layer * cell_size.y,
|
|
row * cell_size.z
|
|
)
|
|
|
|
# Center the position relative to the parent Node3D's origin
|
|
3d_children[index].position = local_pos - offset
|
|
"
|
|
|
|
[node name="AguiGridContainer" type="Node3D" unique_id=1053523827]
|
|
script = SubResource("GDScript_mjcif")
|
|
columns = null
|
|
rows = null
|
|
cell_size = null
|