How do I modify the behavior of a projectile?
You can change the behavior of your Projectiles when requesting its creation to a ProjectileCaller.
The request_projectile method will take your custom functions as parameters.
extends Node2D
@onready var projectile_caller = $ProjectileCaller2D
# In this example the "custom_movement" function is passed as a Callable in the optional "move_method" parameter.
# The ProjectileCaller "request_projectile" method can also change the collision, expiration or target of your projectiles.
func _process(_delta):
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
var destination = get_global_mouse_position()
projectile_caller.request_projectile(0, position, destination, null, custom_movement)
# Each optional Callable argument follows a define pattern and must take a set number of parameters.
# To learn more about these custom methods and how to use them go to the ProjectileCaller section.
func custom_movement(proj: Projectile2D, _delta: float) -> Vector2:
return Vector2.UP
You can also set your Projectiles behaviors and properties beforehand.
extends Node2D
@onready var projectile_caller = $ProjectileCaller2D
func _ready() -> void:
projectile_caller.get_projectile(0).set_on_start(custom_start).set_on_move(custom_movement).set_on_expired(custom_expired).set_on_collision(custom_collision)
# This function will change the projectile "speed" property at projectile creation.
func custom_start(proj: Projectile2D) -> void:
proj.speed = 50
# This function will cause the projectile to always move in the UP direction.
func custom_movement(proj: Projectile2D, _delta: float) -> Vector2:
return Vector2.UP
# This function will print the projectile "damage" once it runs out of pierce or lifetime.
func custom_expired(proj: Projectile2D) -> void:
print(proj.damage)
# This function will change how the projectile collides.
func custom_collision(proj: Projectile2D, body_rid: RID, body_node: Node2D, target_node: Node2D, body_shape_index: int, local_shape_index: int) -> void:
if not proj.validate_collision(body_rid, body_node):
return
# Custom code snippet for immediate expiration on collision with "wall_layer"
if wall_layer & body_node.collision_layer != 0:
proj.is_expired = true
return
proj.on_pierced(body_rid)