The .bind() method creates a new copy of a method with arguments already set. This is useful when you want to pass a method as an argument to a function but need to set some arguments beforehand. It's also useful if you have a generic method and know you will always call it with the same arguments in certain circumstances.This is similar to some uses of a lambda function, although there are some technical differences. More on that later.Here is an example of using bind(). We have two buttons and we want to connect them to a function that will change the current character.
funcchange_character(name:String)->void:print("Selected ", name) current_character = name
func_ready()->void:%SophiaButton.pressed.connect(change_character.bind("Sophia"))%PinkButton.pressed.connect(change_character.bind("Pink"))
The arguments "Sophia" and "Pink" are bound to the change_character() function. When the buttons are pressed, the change_character() function will be called with the corresponding argument.So, writing change_character.bind("Sophia") is equivalent to writing a new function that looks like this:
If you have multiple arguments, the bound arguments will be filled from right to left.For example, if I have two Area2D nodes representing a health pack and a coin. I want to pass this information to the function:
The pinned argument "health" or "coin" is inserted at the right. When collisions happen, the signal itself fills the body argument.The function returned by bind() is a new function entirely separate from the original.
func_ready()->void:var bound_function := change_character.bind("Sophia") bound_function.call()# will print "Selected Sophia"
One quirk of Godot's lambdas and bound functions is that you must explicitly call them using the call() method.
Bound functions and lambdas
Using the bind() method or lambda functions is not strictly equivalent. There are technical differences between the two that are surprising.The bind() method prefills the values you give it as arguments. It immediately evaluates whatever variable you give it.
var current_character :="Sophia"funcshow_character(name:String)->void:print("Current character: ", name)func_ready()->void:var bound_function := show_character.bind(current_character) current_character ="Pink" bound_function.call()# Prints "Current character: Sophia"
On the other hand, lambdas don't always do that. They behave a bit differently depending on the variables you access inside of them:
If you access a script-wide variable inside a lambda, the lambda will keep a reference to this variable. It will not evaluate the variable immediately; it will evaluate it when the lambda is called.
If you access a local variable in a lambda function, the lambda will evaluate the value immediately. It will not keep a reference to the variable to evaluate later because the variable will be destroyed when the function creating the lambda exits.
So, if we use a lambda function instead of bind() in the example above, we get a different result:
func_ready()->void:var lambda_function :=func():show_character(current_character) current_character ="Pink" lambda_function.call()# Prints "Current character: Pink"