Attack2D
Inherits: RefCounted < Object
A basic interface for timed/consecutive Projectile2D spawning.
Description
The Attack2D class is an intermediary state machine designed to assist you in the common task of spawning projectiles. It helps you manage the complete lifecycle of your projectile-based attacks; from charging, to windup, to recovery. In short, use it to delegate the fire rate of your weapons as well as the delay and offset of your attacks.
As a whole, the Attack2D state machine is composed of four phases:
- Charge.
- Anticipation.
- Main.
- Recovery.
Note: Any attack phase with duration of 0 seconds or below margin will be skipped.
Note: Unlike projectiles, assigning custom methods to your attacks will overwrite its “normal” methods. If you want to keep its default functionanily you will have to invoke these “normal functions” inside your custom methods, like this:
extends Node2D
@onready var projectile_manager: ProjectileManager2D = $ProjectileManager2D
func _ready() -> void:
projectile_manager.get_attack(0).set_on_recovery_enter(custom_recovery_enter).set_on_recovery_exit(custom_recovery_exit).set_on_recovery_update(custom_recovery_update)
# As with Projectiles, your Attack methods must follow a defined pattern:
func custom_recovery_enter(attack: Attack2D) -> void:
attack.recovery_enter() # Calling the default behavior for recovery phase start
print("Hi from recovery start")
func custom_recovery_exit(attack: Attack2D) -> void:
attack.recovery_exit() # Calling the default behavior for recovery phase end
print("Goodbye from recovery end")
func custom_recovery_update(attack: Attack2D, delta: float) -> void:
attack.recovery_update(delta) # Calling the default behavior for recovery phase update
print("Greetings from recovery update")
Tutorials
Properties
Methods
Signals
direct_projectile_request(_projectile: Projectile2D, _pi: PackedInfo)
Emitted on ONE_BY_ONE requests.
The most straightway call with the ProjectileProcessor2D. Directly requests the creation of one new projectiles, intentionally skipping projectiles with multiple instances.
modifier_requested(_attack_modifier: Attack2DModifier)
Emitted an Attack2D request the application of an Attack2DModifier.
Directly requests modifier addition to the ProjectileProcessor2D.
projectile_requested(_projectile: Projectile2D, _position: Vector2, _destination: Vector2, _target: Node2D, move_method: Callable, start_method: Callable, collision_method: Callable, expired_method: Callable)
Emitted when an Attack2D request the creation of any new Projectile2Ds.
Directly requests the creation of new projectiles to the ProjectileProcessor2D.
Enumerations
enum AttackChargeTrigger :
AttackChargeTrigger ON_READY = 0
AttackChargeTrigger ON_RELEASE = 1
Attack begins immediately after charging.
Charged attacks begin only when there is no longer any requested_interaction.
enum AttackChargeType :
AttackChargeType CONTINUOUS = 0
AttackChargeType DISCRETE = 1
AttackChargeType MANDATORY = 2
Charge resets if not completed continuously.
Charge accumulates across multiple attempts.
Once the charging phase starts, it cannot be stopped.
enum AttackState :
AttackState ATTACK_CHARGE = 0
AttackState ATTACK_ANTICIPATE = 1
AttackState ATTACK_MAIN = 2
AttackState ATTACK_RECOVERY = 3
Preparation phase before the attack even begins.
Wind-up phase before the main attack.
Active phase where projectiles are spawned.
Cooldown phase after the attack completes.
enum ExecutionType :
ExecutionType MANDATORY = 0
ExecutionType AS_REQUESTED = 1
Once an attack starts, it cannot be stopped.
Multi-instance attacks can be interrupted between shots.
enum InstancesSpawnType :
InstancesSpawnType ALL_AT_ONCE = 0
InstancesSpawnType ONE_BY_ONE = 1
All projectile instances spawn simultaneously.
Projectile instances spawn sequentially with delays.
enum OnInterruptedExecutionContinuation :
OnInterruptedExecutionContinuation REFRESH_SHOTS_AND_START_FROM_ZERO = 0
OnInterruptedExecutionContinuation CONTINUE_FROM_REMAINING_SHOTS = 1
OnInterruptedExecutionContinuation CONTINUE_BUT_NOT_REFRESH = 2
Reset attack to initial state when resumed.
Continue with remaining shots when resumed.
Continue but prevent reloading when resumed.
Property Descriptions
float accumulated_charge = 0
Collective time accumulation for DISCRETE charged attacks.
float attack_anticipate_time = 0
Duration of the anticipation phase in seconds.
float attack_charge_time = 0
Duration of the charge phase in seconds.
float attack_duration_time = 0
Duration of the main attack phase in seconds.
Dictionary[StringName, Attack2DModifier] attack_modifiers = {}
Dictionary of all modifiers affecting this attack.
Vector2 attack_offset = Vector2.ZERO
Added distance to projectile position on creation.
float attack_recovery_time = 0
Duration of the recovery phase in seconds.
ProjectileManager2D caller
Entity that initiated the attack.
Used for flexible position and direction references.
bool can_reload = true
If true
the attack can reload its remaining shoots.
AttackChargeTrigger charge_trigger = 0
Charge completion condition.
AttackChargeType charge_type = 0
Charge accumulation tracking method.
OnInterruptedExecutionContinuation continuation_type = 0
ONE_BY_ONE attacks behavior when resuming interrupted attacks.
float current_state_lifetime = -1
Remaining lifetime of the current attack phase in seconds.
AttackState current_state = 0
Current phase of the attack lifecycle.
Determines which callbacks and methods are executed.
ExecutionType execution_type = 0
ONE_BY_ONE attacks continuation condition.
Dictionary[StringName, Variant] global_properties = {}
This dictionary is shared between all attacks created by its original blueprint.
If you change its values, you will change them in all their attacks.
Dictionary[StringName, Variant] individual_properties = {}
This dictionary is independent in all attacks created by its original blueprint.
Modifying it will only affect this attack instance.
bool instance_attack_modifiers = false
If true
the attack_modifiers dictionary will be independent in all attack copies made by your ProjectileManager2Ds instead of being shared among all of them.
This may seem like the optimal behavior but it is recommended to set it to false
.
int instances = 0
Fixed Projectile instances on request.
bool is_active = false
Variable state for weapon update validation.
bool is_linked = false
If true
the attack itself is connected with the ProjectileProcessor2D and can request projectiles and modify attacks.
bool is_under_uninterrupted_request = false
If true
the original caller has requested new projectiles on every frame without a break.
float margin = 0
Minimum duration for attack phases.
Attack phases below this duration will be skipped.
Callable on_anticipate_enter
Attack custom anticipate phase enter callback.
Callable on_anticipate_exit
Attack custom anticipate phase exit callback.
Callable on_anticipate_update
Attack custom anticipate phase update callback.
Callable on_charge_enter
Attack custom charge phase enter callback.
Callable on_charge_exit
Attack custom charge phase exit callback.
Callable on_charge_update
Attack custom charge phase update callback.
Callable on_completed
Attack custom completion callback.
Callable on_main_enter
Attack custom main phase enter callback.
Callable on_main_exit
Attack custom main phase exit callback.
Callable on_main_update
Attack custom main phase update callback.
Callable on_recovery_enter
Attack custom recovery phase enter callback.
Callable on_recovery_exit
Attack custom recovery phase exit callback.
Callable on_recovery_update
Attack custom recovery phase update callback.
Callable on_start
Attack custom start callback.
bool override_attack_duration = false
If true
overrides the attack_duration_time property with its assign projectile spawn_interval value.
bool override_direction = false
If true
the attack ignores the given requested destinations and uses its own ProjectileManager2D Node right direction instead. See Transform2D.x.
bool override_position = false
If true
the attack ignores the given spawn positions and uses its own ProjectileManager2D Node global position instead.
PackedInfo pi
Projectile spawn parameters.
Projectile2D projectile
Reference to the requested projectile.
Defines what gets spawned during the attack.
int remaining_shots = 0
Current attack repetitions until expiration.
Only available on ONE_BY_ONE executions.
bool requested_interaction = false
If true
the original caller has requested the creation of more projectiles on this frame.
AttackBlueprint2D resource
Fixed attack blueprint.
InstancesSpawnType spawn_type = 0
Determines the spawning method of projectiles with multiple instances and with timed spawn intervals:
- ALL_AT_ONCE: All projectile instances spawn simultaneously.
- ONE_BY_ONE: Projectile instances spawn sequentially with delays.
float sub_frame_excess = 0
Remnant for attacks with lifetimes below framerate.
Only available on ONE_BY_ONE executions.
Method Descriptions
void _init(_resource: AttackBlueprint2D = null, proj_caller: Node2D = null)
Initializes a new attack instance from the values of the given AttackBlueprint2D _resource
parameter.
Attack2D add_global_property(property: StringName, value: Variant)
Returns itself for method chaining.
Adds a new element at the global_properties dictionary, with the given value
at the given key property
.
var attack_1: Attack2D = projectile_manager.get_attack(0)
var attack_2: Attack2D = projectile_manager.get_attack(0).clone()
attack_1.add_global_property("RECOIL", 11.5)
print(attack_1.global_properties["RECOIL"]) # Prints (11.5)
print(attack_2.global_properties["RECOIL"]) # Also prints (11.5)
Attack2D add_individual_property(property: StringName, value: Variant)
Returns itself for method chaining.
Adds a new element at the individual_properties dictionary, with the given value
at the given key property
.
var attack_1: Attack2D = projectile_manager.get_attack(0)
var attack_2: Attack2D = projectile_manager.get_attack(0).clone()
attack_1.add_individual_property("DURABILITY", 100)
print(attack_1.individual_properties.get("DURABILITY", -1)) # Prints (100)
print(attack_2.individual_properties.get("DURABILITY", -1)) # Prints (-1.0) because "DURABILITY" does not exist here
bool add_modifier(modifier: Attack2DModifier)
Returns true
if modifier
was successfully added.
If valid, modifier
gets added to attack_modifiers and emits the modifier_requested signal.
It is strongly recommended to use your ProjectileManager2D add_attack_modifier method instead.
var attack: Attack2D = projectile_manager.get_attack(0)
attack.add_modifier(Attack2DModifier.new("ATTACK_BUFF", 1.0))
void anticipate_enter()
Default behavior for anticipate phase start.
void anticipate_exit()
Default behavior for anticipate phase end.
void anticipate_update(_delta: float)
Default behavior for anticipate phase update.
void assign(_projectile: Projectile2D, _caller: ProjectileManager2D, _pi: PackedInfo = pi)
Set up an attack essential parameters.
bool change_state(state: AttackState)
Transitions to new state
attack phase.
Also calls its appropriate enter callbacks.
void charge_enter()
Default behavior for charge phase start.
void charge_exit()
Default behavior for charge phase end.
void charge_update(_delta: float)
Default behavior for charge phase update.
Attack2D clone()
Returns an identical copy of the attack.
void copy(base: Attack2D)
Copies all properties from the base
attack.
void direct_request(_projectile: Projectile2D = projectile, _pi: PackedInfo = pi)
Requests the creation of new projectiles through the direct_projectile_request signal.
void disable()
Interrupts/completes the attack sequence.
Calls on_completed callback.
float get_current_state_duration()
Returns duration of the current attack phase, whatever it may be.
bool is_charge_completed()
Returns true
if the charge phase is completed.
Depends on charge_trigger setting.
void link_to_processor(processor_instance: ProjectileProcessor2D)
Connects all attack signals to the given ProjectileProcessor2D instance.
void main_enter()
Default behavior for main phase start.
Sets up projectile spawning on ALL_AT_ONCE executions.
void main_exit()
Default behavior for main phase end.
void main_update(_delta: float)
Default behavior for main phase update.
Handles projectile spawning on ONE_BY_ONE executions.
void recovery_enter()
Default behavior for recovery phase start.
void recovery_exit()
Default behavior for recovery phase end.
Completes the attack.
void recovery_update(_delta: float)
Default behavior for recovery phase update.
void reload(proj: Projectile2D)
Sets proj
as its projectile and proj.instances
as its remaining_shots on ONE_BY_ONE executions.
bool remove_modifier(modifier_name: StringName)
Returns true
if the modifier with key modifier_name
was successfully removed.
Removes a modifier by name from attack_modifiers and calls its exit() method.
It is strongly recommended to use your ProjectileManager2D remove_attack_modifier method instead.
var attack: Attack2D = projectile_manager.get_attack(0)
attack.remove_modifier("ATTACK_BUFF")
void request_projectile(_projectile: Projectile2D = projectile)
Requests the creation of new projectiles through the projectile_requested signal.
void reset()
Resets the attack to its initial state using its blueprint.
Clears all runtime modifications and custom properties.
Attack2D set_on_anticipate_enter(method: Callable)
Returns itself for method chaining.
Sets on_anticipate_enter callback.
Attack2D set_on_anticipate_exit(method: Callable)
Returns itself for method chaining.
Sets on_anticipate_exit callback.
Attack2D set_on_anticipate_update(method: Callable)
Returns itself for method chaining.
Sets on_anticipate_update callback.
Attack2D set_on_charge_enter(method: Callable)
Returns itself for method chaining.
Sets on_charge_enter callback.
Attack2D set_on_charge_exit(method: Callable)
Returns itself for method chaining.
Sets on_charge_exit callback.
Attack2D set_on_charge_update(method: Callable)
Returns itself for method chaining.
Sets on_charge_update callback.
Attack2D set_on_completed(method: Callable)
Returns itself for method chaining.
Sets on_completed callback.
Attack2D set_on_main_enter(method: Callable)
Returns itself for method chaining.
Sets on_main_enter callback.
Attack2D set_on_main_exit(method: Callable)
Returns itself for method chaining.
Sets on_main_exit callback.
Attack2D set_on_main_update(method: Callable)
Returns itself for method chaining.
Sets on_main_update callback.
Attack2D set_on_recovery_enter(method: Callable)
Returns itself for method chaining.
Sets on_recovery_enter callback.
Attack2D set_on_recovery_exit(method: Callable)
Returns itself for method chaining.
Sets on_recovery_exit callback.
Attack2D set_on_recovery_update(method: Callable)
Returns itself for method chaining.
Sets on_recovery_update callback.
Attack2D set_on_start(method: Callable)
Returns itself for method chaining.
Sets on_start callback.
Attack2D set_property(property: StringName, value: Variant)
Returns itself for method chaining.
Assigns value
to the given attack property
. If the attack property does not exist or the given value
's type doesn't match, nothing happens.
var attack: Attack2D = projectile_manager.get_attack(0)
attack.set_property("attack_duration_time", 2.5)
print(attack.attack_duration_time) # Prints (2.5)
void start()
Validates and initiates the attack phases sequence.
bool update_lifetime(_delta: float, local_margin: float = 0)
Updates the current attack phase lifetime.
Returns true
as long as the current phase remains active.
bool update(_delta: float)
Updates the attack state machine.
Returns true
as long as the attack itself remains active.
bool validate_attack()
Returns true
if the attack can be executed.
A valid attack requires direct processor connection and a valid projectile.