For my current project I wanted to simulate a light that's shorting out in order to add a bit of a creepy ambience to my scene. After a while of messing with the different things that could be done with an emitter (and failing at getting the effect I wanted), I realized that really, a light that's shorting out is really a light that's turning off and on again. Well, that's something that can be scripted pretty easily thanks to Leadwerk's API.
There are a couple of obvious ways to get the desired effect:
- Create the light in a given position, then remove it again. This can be a pain and can also be resource intensive
- Toggle the light's color between the "on" and "off" colors, where "off" is transparent and "on" is any color with a visible alpha.
Needless to say, I chose the latter.
First I needed to define some colors. For my purposes, I wanted to be able to set colors between Red, Green, Blue, and White, so in my Scripts/Objects/Lights/ShortedBlink.lua file I added the following:
function Script:Start() self.colors = {} self.colors["red"] = Vec4(1, 0, 0, 0) self.colors["green"] = Vec4(0, 1, 0, 0) self.colors["blue"] = Vec4(0, 0, 1, 0) self.colors["white"] = Vec4(1, 1, 1, 0) if self.color_on == nil then self.color_on = self.colors[string.lower(self.OnColor)] end self:On() end
Then it came time to fill in the "on()" and "off()" functions:
function Script:On() self.entity:SetColor(self.color_on) self.component:CallOutputs("On") self.isOn = true end function Script:Off() self.entity:SetColor(self.color_off) self.component:CallOutputs("Off") self.isOn = false end
I then defined a few top-level variables that I knew I would need, one of which needed to be available to the Leadwerks Editor, namely "OnColor" (the desired activated color). Here's what the top of the file looks like:
Script.enabled = true Script.isOn = true Script.OnColor = "red" -- string "Active Color" Script.color_on = nil -- transparent Script.color_off = Vec4(0, 0, 0, 0)
Now that I had my top-level variables defined coupled with on and off functions, it was time to add a ToggleLight() function that would do the work:
function Script:ToggleLight() if self.isOn then self:Off() else self:On() end end
Pretty self-explanatory. If isOn is true then the light is on, so turn it off, else turn it on.
This script is missing one thing: UpdateWorld()
function Script:UpdateWorld() self:ToggleLight() end
I was pretty happy with myself up until I attached this script to a spotlight and almost suffered an epileptic seizure...
Thankfully, the answer was pretty clear: I needed to add some sort of a delay. After some experimentation, the desired effect was achieved by performing some modulo division:
function Script:UpdateWorld() if Time:Millisecs() % 11 == 0 then self:ToggleLight() end end
Basically, we're taking the current time in milliseconds and seeing if it's evenly divisible by 11. If it is, then toggle the light, else leave the light's state alone. I probably could have gone with a better way of randomizing the delay, but this one works just fine and isn't resource intensive at all (if a computer struggles to perform a simple math operation, put it out of its misery).
The completed script looks like this:
Script.enabled = true Script.isOn = true Script.OnColor = "red" -- string "Active Color" Script.color_on = nil -- transparent Script.color_off = Vec4(0, 0, 0, 0) function Script:Start() self.colors = {} self.colors["red"] = Vec4(1, 0, 0, 0) self.colors["green"] = Vec4(0, 1, 0, 0) self.colors["blue"] = Vec4(0, 0, 1, 0) self.colors["white"] = Vec4(1, 1, 1, 0) if self.color_on == nil then self.color_on = self.colors[string.lower(self.OnColor)] end self:On() end function Script:On() self.entity:SetColor(self.color_on) self.component:CallOutputs("On") self.isOn = true end function Script:Off() self.entity:SetColor(self.color_off) self.component:CallOutputs("Off") self.isOn = false end function Script:ToggleLight() if self.isOn then self:Off() else self:On() end end function Script:UpdateWorld() if Time:Millisecs() % 11 == 0 then self:ToggleLight() end end
Just add the script to a light source, type in the color you want (from the choices available within the script) and watch what happens the next time you debug or play your game.
Hopefully this saves someone some time in the future.
2 Comments
Recommended Comments