Hi all! A question from newbe - I make a simplistic RTS prototype to plays with various game mechanics and learn Godot.
Currently my sandbox looks as follows:
Locations - spawn units
Units - move betwen locations
Both Locations and Units are Area2D, can be selected on a mouse click, all attached to a root Node2d.

Question I have - what will be the best way to deselect other units on click?
I currently look into the following:
1) make a 'cursor' object that once select a new Location or Unit - will emit signal to others to get deselected
2) selected Location/Unit sends a signal to Root node and the latter looks into all its Location and Unit children and makes them deselected. Appreciate your recommendation on what will be the best way to iterate thru the children nodes.

Can you please suggest what will be the best approach, what I can be missing here. What patterns are commonly used in games without map grid?

imho you are making simple logic complicated, to deselect unit, you just need to deselect all upon zero/no result from camera space raycast test.

    MagickPanda
    May I ask you for more details? Or at least keywords to Google "camera space raycast". What I'm finding now doesn't look relevant.

      thanks will try. After additional research I finally figured out that raycast from the camera is one of the ways described in Godot official docs. Need to come back and learn the basics.

      I know code has already been posted up but been working on this myself, also signals are your friend for doing lots of code without it executing every frame.

      
      extends Spatial
      
      onready var playerCameraGroup = get_tree().get_nodes_in_group("PlayerCamera")
      onready var playerCamera = playerCameraGroup[0]
      
      var buildingSlots
      
      var mouseInteractionEnabled = true
      
      var rayOrigin = Vector3()
      var rayEnd = Vector3()
      
      var previousSelection
      var currentSelection
      
      var currentPlayerArmyPosition = Vector3()
      var clickPosition = Vector3()
      
      func _physics_process(_delta):
      	
      	var spaceState = get_world().direct_space_state
      	var mousePosition = get_viewport().get_mouse_position()
      	
      	rayOrigin = playerCamera.project_ray_origin(mousePosition)
      	rayEnd = rayOrigin + playerCamera.project_ray_normal(mousePosition) * 10000
      	var intersection = spaceState.intersect_ray(rayOrigin, rayEnd)
      	
      	if Input.is_action_just_pressed("RightClick"):
      		if intersection.collider.is_in_group("Floor"):
      			clickPosition = intersection.position
      		
      	if Input.is_action_just_pressed("LeftClick") and mouseInteractionEnabled == true:
      		if not previousSelection == null:
      			previousSelection.visible = false
      		if intersection.collider.is_in_group("PlayerArmy"):
      			currentSelection = intersection.collider.get_child(0)
      			currentSelection.visible = true
      			previousSelection = currentSelection
      			print ("Player Army Selected")
      			
      			if not buildingSlots == null:
      				buildingSlots.visible = false
      			
      		if intersection.collider.is_in_group("PlayerTown"):
      			currentSelection = intersection.collider.get_child(0)
      			currentSelection.visible = true
      			previousSelection = currentSelection
      			
      			buildingSlots = intersection.collider.get_child(1)
      			buildingSlots.visible = true
      			
      			print ("Player Town Selected")
      		if intersection.collider.is_in_group("NeutralTown"):
      			currentSelection = intersection.collider.get_child(0)
      			previousSelection = currentSelection
      			print ("Neutral Town Selected")
      			
      			if not buildingSlots == null:
      				buildingSlots.visible = false
      			
      		if intersection.collider.is_in_group("EnemyTown"):
      			currentSelection = intersection.collider.get_child(0)
      			currentSelection.visible = true
      			previousSelection = currentSelection
      			print ("Enemy Town Selected")
      			
      			if not buildingSlots == null:
      				buildingSlots.visible = false
      			
      		if intersection.collider.is_in_group("Floor"):
      			if not previousSelection == null:
      				previousSelection.visible = false
      			if not currentSelection == null:
      				currentSelection.visible = false
      				print ("Floor Selected")
      			if not buildingSlots == null:
      				buildingSlots.visible = false
      			
      		if intersection.collider.is_in_group("OutOfBounds"):
      			if not previousSelection == null:
      				previousSelection.visible = false
      			if not currentSelection == null:
      				currentSelection.visible = false
      			if not buildingSlots == null:
      				buildingSlots.visible = false
      
      
      func _on_Button_mouse_entered():
      	mouseInteractionEnabled = false
      
      func _on_Button_mouse_exited():
      	mouseInteractionEnabled = true
      
      func _on_EndTurnButton_mouse_entered():
      	mouseInteractionEnabled = false
      
      func _on_EndTurnButton_mouse_exited():
      
      	mouseInteractionEnabled = true

      Worth pointing out that this is only for clicking on single units and stuff on the map, I haven't messed about with box selection as of yet.