How to make a player select something (for example an enemy) in a turn based game

Godot Version

4.5.1

Question

Hey i’m looking for a way to make a player select an enemy in something like a turn-based rpg. to be specific, so far i have set up a command menu using UI elemenets and would like to know how to give a player a chance to select an enemy after clicking “attack” for example, so far i have tried using “await” but i’ll be honest i don’t really understand it, as well as a “while loop” and a “recersive call function” both of the latter resolting in the game crashing. Any help if apprciated + sorry for bad english.

If everything is made of controls, you can check for clicks via _gui_input(). If it’s made of other nodes, you can check via _input() or _unhandled_input().

After the player selects an attack, you can set a boolean such as _choosing_enemy. While the condition is true, you allow the enemy nodes to accept mouse clicks, and send a signal when one is clicked (for example). Once the signal is received, _choosing_enemy is now false, and you perform whatever you need on said enemy.

2 Likes

I don’t see how await or while loops would help you achieve your goal here, so leave them aside for now.

It would be best if you showed us how you attempted doing it by pasting the code (as preformatted text between the three backticks ```), and showing some screenshots, then we can see how best to solve your issue.

ye sure here is what i got going

main script :

extends Node2D

var list_of_enemies : Array[Enemy]

func _ready() → void :

SignalBus.Main_Scene = self	
SignalBus.connect("pass_get_taget_signal", _getTarget)
SignalBus.connect("get_target", _getTarget)

UpdateActiveEnemies()

func UpdateActiveEnemies() → void :

list_of_enemies.clear()

for child in get_children() :
	
	if child is Enemy :
		
		list_of_enemies.append(child)

func _getTarget() → void :

var target : Enemy = null

print("got to main")

target = _selectTarget() 

if target != null : 
	
	SignalBus.emit_signal("return_target", target)

func _selectTarget() → Enemy :

if list_of_enemies.is_empty() :
	
	return null
	

for enemy in list_of_enemies :
	
	if enemy.hovered and Input.is_action_just_pressed("UI_click_left") :
		
		return enemy
		
	

return null

enemy class :

class_name Enemy extends Area2D


var hovered : bool = false


func _ready() -> void :
	
	connect("area_entered", toggle_hovered)
	connect("area_exited", toggle_hovered)
	


func toggle_hovered() -> void :
	
	hovered = not hovered
	

Signal bus :

extends Node

signal get_target
signal return_target(target : Area2D)

var Command_holder : Node2D
var Main_Scene : Node2D

command holder :

extends Node2D

enum TURN_STATE {
	
	PLAYER_TURN,
	IN_BETWEEN,
	OPPONENT_TURN
	
}

@onready var attack_button : Button = $CommandButtonHolder/AttackButton
@onready var pass_button : Button = $CommandButtonHolder/PassButton

var current_turn : TURN_STATE = TURN_STATE.PLAYER_TURN

func _ready() -> void :
	
	SignalBus.Command_holder = self
	
	SignalBus.connect("return_target", _processTarget)
	
	attack_button.pressed.connect(_attackPressed)
	pass_button.pressed.connect(_passPressed)
	


func _attackPressed() -> void :
	
	if current_turn != TURN_STATE.PLAYER_TURN :
		
		return
		
	
	current_turn = TURN_STATE.IN_BETWEEN
	
	SignalBus.emit_signal("get_target")
	
	return
	


func _passPressed() -> void :
	
	if current_turn != TURN_STATE.PLAYER_TURN :
		
		return
		
	


func _processTarget(target : Enemy) -> void :
	
	print(target)
	

thank for the input just to clearify the enemies are not UI elemets they are a class that extends Area2D, i will try what you are suggesting however it will require a code overhaul so give me sometime

you thanks a bunch, had to tweak some stuff but worked like a charm :slight_smile:

1 Like