I feel that using an array might be not be the best answer here. Really it depends on whether you want them to be able to split up again in an organized way or not. I would just make like, the main node in charge of what groups get added together, and just add them as children of a new, higher up group node.
extends Node
# main script, on the root node
var Hey: GroupNode = $Hey # your groups
var What : GroupNode = $What
func conjoin( A : GroupNode, B : GroupNode) -> GroupNode:
var Parental : GroupNode = GroupNode.new()
#give the new parent node the coordinates of one of the groups, or make it somwhere in between
#if you wanted it to be the average between the two of them, im pretty sure using = A.Transform2D - B.Transform2D works
Parental.Transform2D = A.Transform2D
A.reparent(Parental, true)
B.reparent(Parental, true) # Set to true otherwise it moves to its parents coordinates
return Parental
if you want them to only be able to do that while theyre colliding AND while a player is pressing a button, you’ll want to have access to some internal state from the groups to check when the player pressses a button, and im guessing you’d want them to still be like, some kind of platform for the player to jump on? so you could do this
class_name Group
extends Area2D
# export so you can choose the shape in the editor
# go with collisionpolygon not collisionshape becase we can do stuff with its polygons
@export var HitBox : CollisionPolygon2D
var AmIColliding : bool = false
var WhoIsTouchinMe : Array[Group]
func _physics_process(delta: float) -> void:
if(has_overlapping_areas()):
WhoIsTouchinMe.clear()
var Areas : Array[Area2D] = get_overlapping_areas()
for Area in Areas:
if Area is Group:
AmIColliding = true
WhoIsTouchinMe.append(Area)
else:
AmIColliding = false
func polygons_please() -> PackedVector2Array:
HitBox.disabled
return HitBox.polygon
and then on your main script
extends Node
# still the main script, on the root node
var ChildGroups : Array[Group]
func _ready() -> void:
var Children : Array[Node] = self.get_children()
for Child in Children:
if Child is GroupNode: # gather all the groups in one place
ChildGroups.append(Child)
func player_pressed_the_button() -> void:
var GroupCollision : bool = false
for GroupNode in ChildGroups:
if(GroupNode.AmIColliding):
GroupCollision = true
if(!GroupCollision):
return
# end the function here if theres no colliding groups
var NewGroupArray : Array[Group]
var NewPolygons : PackedVector2Array
var NewGroupParent : Group
for GroupNode in ChildGroups:
if(GroupNode.AmIColliding):
NewPolygons.append_array(GroupNode.polygons_please())
GroupNode.reparent(NewGroupParent, true)
else: # probably set the transform2d somwehere, im tired
NewGroupArray.append(GroupNode) # keep any uncollided groupnodes in an array where we can find them
var HitBox : CollisionPolygon2D = CollisionPolygon2D.new()
# the way 2d collision shapes are calculared is pretty simple, and somhow this actually works
HitBox.polygon = NewPolygons
NewGroupParent.add_child(HitBox)
# joined node rright at the end of the array, easy to find. just use array.back()
NewGroupArray.append(NewGroupParent)
ChildGroups.clear() # replace old array with new one
ChildGroups.append_array(NewGroupArray)
and you can just check from whatever script you put on the groups that join up to check if they’ve had their hitboxes disabled to know if thheve been adjoined. this is a bit overkill if you only wanted two groups, but technically it can work for however many you want. if you want them to be able to break up again just make the new parent nodes a class that extends group like “groupparent” or something. they could either join more groupparents together and make a tree-like structure, or you could just have one megaparent that holds them all and can break them off individually.
but yeah i spent way longer on this than i thought i would. Just ask if you need any further help or anything