I would approach it by creating an abstract class Ability
that extends Resource
and will be extended by your actual abilities, like MeleeAttack
, RangedAttack
, Dash
, Copy
, etc.
class_name Ability
extends Resource
func trigger() -> void:
pass # we don't want any logic here, as it should be overridden by actual abilities
class_name MeleeAttack
extends Ability
func trigger() -> void:
# your melee attack logic
class_name RangedAttack
extends Ability
func trigger() -> void:
# your ranged attack logic
Once you have the *.gd
scripts with the logic, you need to create the actual Resource *.tres
.
Your character should have a list of abilities that you can then assign through inspector.
Let’s assume your abilities are triggered with buttons 1, 2, …, 9, etc. the logic would be something like that. You just need to create 9 actions in your project settings called “ability_1”, “ability_2”, …, “ability_9”, etc. and assign 1-9 buttons to them respectively.
class_name Character
extends CharacterBody3D
@export var abilities: Array[Ability]
func _unhandled_input(event: InputEvent) -> void:
for i in range(1, 10):
if event.is_action_pressed("ability_%s" % i) and abilities.size() >= i:
abilities[i - 1].trigger()
That’s more or less how I implemented it in my turn based game, where several units types have unique abilities.
This way it’s modular and isn’t hardcoded per character. You can add and remove abilities from your character even at runtime if you like.
As for your copy ability specifically - I haven’t played the game you mentioned, but you probably want to perform the same ability that your opponent has performed last. In this case, you should store the last ability performed by a character in a variable, and then when you trigger your copy ability, it would look at this variable on the opponent character and trigger that specific ability.
Let me know in case you have issues implementing this in your game.