I doubt you will have to use a different solution, the issue adding function parameters is almost inherit in programming languages, that will affect you everywhere in programming. Your sample code is perfectly reasonable.
You could use it as-is, the pros being that it’s simple and not limiting, only requiring a function definition. cons are that it could be hard to debug, say you misspell a func hut
, your code would simply ignore the collision, though this is an equal issue with the alternatives.
There are usually two schools of systems in games, Godot as an outlier prefers inheritance, where Unity and Unreal use a component based approach to system design.
Inheritance
You could use an inheritance based systems like so
# Colliding body
extends CharacterBody2D
class_name Hittable
var health: int = 100
func hit(damage: int) -> void:
health -= damage
if health <= 0:
self.queue_free()
With the class_name
you can detect the type of body with is
, and the Hittable class can be extended for more variables or a more complex hit
function, so long as it has the same number of arguments. This also has auto-complete because it uses the static type system.
func _on_body_entered(body: Node2D) -> void:
if body is Hittable:
body.hit(10)
Composition
In a composed system you would give a child “Node” a script for health or taking damage, then you can check if the colliding body has that node, or use metadata to get the component.
# Child of colliding body
extends Node
class_name HealthComponent
var health: int = 100
func hit(damage: int) -> void:
health -= damage
if health <= 0:
get_parent().queue_free()
Shockingly similar to the inheritance script, but must be retrieved differently. The pros for composed systems is that the HealthComponent can be added as a child to any other node, CharacterBodies, RigidBodies, even StaticBodies. It does not interfere with the parent node’s type. The con being more difficult to manage, this incurs more scene tree searching than the other methods.
func _on_body_entered(body: Node2D) -> void:
var health: HealthComponent = body.get_node_or_null("HealthComponent")
# or via metadata `body.get_meta("HealthComponent", null)`
if health:
health.hit(10)