Cross-Behaviour Calls
In Lemonate, game logic is defined through Behaviour — Lua scripts attached to Scene Objects. Sometimes, one behaviour script needs to call a function defined in another behaviour attached to a different object in the scene graph.
To enable this, Lemonate provides the :behaviour() method on the SceneObject type. This method allows you to access another behaviour scripts by specifying its script item name as a string.
How Cross-Behaviour Calls Work
In Lemonate, Lua does not have type names or reflection features like some other languages. This means you cannot refer to behaviour types directly. Instead, the :behaviour(scriptName) method retrieves the instance of a specific script attached to a node, using the script file name.
Note
The string you pass to :behaviour() must match the item name of the Lua script that defines the behaviour, not the name of the Behaviour that is created inside. This is necessary because Lua does not provide native support for type introspection.
Usage Example
Let's say you have two scene objects:
- A Controller object with a script named
MyController - A Box object with a script named
BoxController
You want the Controller to call a method on the Box each frame to move it upward.
BoxController
This script defines a method moveBox(translation) on the box behaviour:
local BoxBehaviour = Class.new(Behaviour)
function BoxBehaviour:moveBox(translation)
self.node:withTransform(function(t)
t.position.add(translation)
end)
end
return BoxBehaviour
ControllerBehaviour
This script references the Box behaviour and calls its method during the update loop. Note that it is using the script item's name "BoxController", not "BoxBehaviour" which is the behaviour's name created in the script. In practice, those names should match but it is not guaranteed.
local Vector3 = require 'engine/math/vector3'
local ControllerBehaviour = Class.new(Behaviour)
ControllerBehaviour:addProperty("box", Property.Node)
function ControllerBehaviour:update()
self.box:behaviour("BoxController"):moveBox(Vector3.new(0, 1, 0))
end
return ControllerBehaviour
Explanation
self.boxis a node property (set up via the editor or manually).self.box:behaviour("BoxController")returns the behaviour script instance namedBoxControllerattached to the node.:moveBox(...)then calls the method on that script instance.
Best Practices
- Make sure that the script name passed to
:behaviour()matches the item name exactly. - Use addProperty("nodeName", Property.Node) to link scene objects to each other via the editor.
- Always check that the target object and behaviour exist before calling methods in more complex scenarios.
Example with Null Check:
function ControllerBehaviour:update()
if self.box then
local boxController = self.box:behaviour("BoxController")
if boxController then
boxController:moveBox(0, 1, 0)
end
end
end
Summary
- Use
:behaviour(scriptItemName)to call methods on another behaviour script. - This enables communication between different objects in the scene graph.
- Script names (not type names) must be used due to Lua's limitations.
- Use this feature when you want modular, decoupled components that interact via explicit links.