Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Attack and Projectile Signals

A topic by m0nkeybusiness created 29 days ago Views: 41 Replies: 2
Viewing posts 1 to 3

First of all amazing plugin! Exactly what I need for my game! Works like a charm.

Maybe I missed that in your documentation so far but I got a question:

How can I access methods of the attacks and projectiles. Are there signals available? 

For instance: I would like to set a variable or execute a function when the attack goes into recovery mode or leaves recovery mode. An example would be awesome. TY

Developer (6 edits)

Modifying your projectiles and attacks behaviors is a bit complex but bear with me.

Let’s say I want to modify a projectile speed, right at the start of instancing it. First, I need to create a function that modifies ANY projectile:

# In this example the parameter “proj” is a representation of the Projectile to modify.
# So in order to modify its speed, I need to change the speed property of “proj”
func custom_start(proj: Projectile2D) -> void:
	proj.speed = 50

Then I would have to attach it to my desired projectile, like this:

# In this example, I’m requesting and modifying the projectile with index “0” of the “Projectile Resources” array
projectile_manager.get_projectile(0).set_on_start(custom_start)

# To be clear, you can reuse the “custom start” function to modify any other projectile, like this:
projectile_manager.get_projectile(1).set_on_start(custom_start)
projectile_manager.get_projectile(2).set_on_start(custom_start)

At the end, you should have a script similar to this:

extends Node2D

@onready var projectile_manager: ProjectileManager2D = $ProjectileManager2D


# In this example the "custom_start" function is set as the "start_method" of the projectile at index “0”.
func _ready() -> void:
	projectile_manager.get_projectile(0).set_on_start(custom_start)

			
func _process(_delta: float):
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		projectile_manager.request_execution(0, 0, position, get_global_mouse_position())


# This function will change the projectile "speed" property at projectile creation.
func custom_start(proj: Projectile2D) -> void:
	proj.speed = 50

You can change all projectile behaviors in this way:

func _ready() -> void:
	projectile_manager.get_projectile(0).set_on_start(custom_start).set_on_move(custom_move).set_on_collision(custom_collision).set_on_expired(custom_expired)

The documentation is not yet up to date, but this page should give you an idea of the form and parameters needed for each behavior method.


Now, attacks work almost the same. Using your question I can modify an attack internal and external variables and methods on its recovery phase like this:

func _ready() -> void:
	projectile_manager.get_attack(0).set_on_recovery_enter(custom_recovery_enter).set_on_recovery_exit(custom_recovery_exit)


func custom_recovery_enter(attack: Attack2D) -> void:
	attack.attack_duration_time += 0.5
	attack.request_projectile()

	attack.projectile.instances += 1

	enter_executions += 1
	on_enter()


func custom_recovery_exit(attack: Attack2D) -> void:
	attack.attack_duration_time += 0.5
	attack.request_projectile()

	attack.projectile.instances += 1

	exit_executions += 1
	on_exit()

However THIS WILL NOT WORK, because unlike projectiles, assigning custom methods to your attacks will overwrite its “normal” methods.

To recover its normal functionality you will have to invoke the “normal functions” inside your custom methods, like this:

func custom_recovery_enter(attack: Attack2D) -> void:
	attack.recovery_enter()

func custom_recovery_exit(attack: Attack2D) -> void:
	attack.recovery_exit()

So you will end up with a script like this:

extends Node2D

@onready var projectile_manager: ProjectileManager2D = $ProjectileManager2D

var enter_executions: int
var exit_executions: int


func _ready() -> void:
	projectile_manager.get_attack(0).set_on_recovery_enter(custom_recovery_enter).set_on_recovery_exit(custom_recovery_exit)


func _process(_delta: float):
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		projectile_manager.request_execution(0, 0, position, get_global_mouse_position())


func custom_recovery_enter(attack: Attack2D) -> void:
	attack.recovery_enter()

	attack.attack_duration_time += 0.5
	attack.request_projectile()

	attack.projectile.instances += 1

	enter_executions += 1
	on_enter()


func custom_recovery_exit(attack: Attack2D) -> void:
	attack.recovery_exit()

	attack.attack_duration_time += 0.5
	attack.request_projectile()

	attack.projectile.instances += 1

	exit_executions += 1
	on_exit()


func on_enter() -> void:
	print("Hi, there are %d enter executions" % enter_executions)


func on_exit() -> void:
	print("Goodbye, there are %d exit executions" % exit_executions)

Remember, in order to see these changes, your attack blueprint “attack recovery time” property should be greater than zero, otherwise the “recovery phase” will just be skipped.

Hope that helps!

Any other questions I am here to help!

Wow. What a detailed explanation. Perfect support.

Thank you so much!