Let's start by looking at some code to understand how variable scoping works. Here we have some script that lives in a Trigger's script:
shared_enter_count = 0
Trigger.enter_count = 0
function Trigger:onEnter(obj)
self.enter_count = self.enter_count + 1
shared_enter_count = shared_enter_count + 1
end
Here we have two variables that hold a number that represents the total number of times the Trigger fires. The 'shared_enter_count' variable is shared amongst all shared Trigger copies and thus would represent the total number of fired events amongst all instances. The 'Trigger.enter_count' (accessed via the 'self' keyword within a Trigger member function) would only reflect the number of times a specific instance of the Trigger fires.
Instance variables are a good way to maintain custom object state, especially for things like Actors. For instance, we could have a variable that represents a character's health that would be incremented and decremented depending on what happens to the character:
Unit.health = 100 --initialize to this
function Unit:getHealth() return self.health end
function Unit:addHealth(val) self.health = self.health + val end
function Unit:onSomethingScaryProbably()
self.health = self.health - 1
if self.health == 0 then
GameOverTimeline = findObjectByUid("DFF2")
GameOverTimeline:play()
end
end
If we wish to query the character's health value from our Trigger, we can just call the member functions directly:
function Trigger:onEnter(obj)
if obj:getName() == "player" then
if obj:getHealth() < 10 then
print("You don't look so hot. Here, let me give you a hug.")
obj:addHealth(1000000)
end
end
end
In general, it's best to initialize variables that don't change only once inside an object's 'onInit()' event. For instance, in the following example, we pre-fetch objects once so we don't need to find them each time a ConstantPulse's 'onPulse' event fires.
function ConstantPulse:onInit() self.Space = findObjectByUid("D1CF") self.Player = self.Space:findNodeByName("Player") self.Cat = self.Space:findNodeByName("Cat") end function ConstantPulse:onPulse(uSubEvents) v = self.Cat:getWorldPosition() - self.Player:getWorldPosition() if v:length() < 1 then print("Player within petting range. Beware: this cat may have ticks.") end end
Notice how we store the found objects inside the 'self' so we can access them from other functions.
If we don't wish for a variable to be added to the Script's environment, we can define it as 'local':
function Trigger:onEnter(obj)
local obj_name = obj:getName()
if obj_name == "player" then
obj.active = false
end
end
Here 'obj_name' will only exist until the function returns. Note that any variables defined within functions without the local keyword will be added to the Script's enviroment and thus shared amongst all instances.
Comments
0 comments
Please sign in to leave a comment.