Hey @BazZy.
I am using GUI Objects for this. I am cloning a prototype of it. Of cause - for a new one in game-dev and this engine - it may be a little confusing and hard to understand.
You may ask if you’re in trouble with it.
- The GUI elements in my ingame.gui:
(the small 2 bars you see left with the arrows, or right in the outline highlighted. These are simple GUI-boxes)
Note that all “un-sprited” boxes have their own layer! This is important to prevent to many drawcalls!
- In the ingame.guiscript I have several functions for.
2.1. If a unit (in my case) has build/spawned it will call (message) the ingame.gui for creating (cloning) the unit-bar-templates (seen at the screen above).
The code (at UNIT.SCRIPT) looks like this:
-- initiate UNIT-BARS (energy + hp)
msg.post("main:/ingamegui#ingame", "unit_bar", {create = true, unitid = go.get_id(), pos = self.pos + vmath.vector3(-16, 16, 0), energy = GLOBAL.TILESIZE / self.unit.energyMax * self.unit.energy, health = GLOBAL.TILESIZE / self.unit.hitpointsMax * self.unit.hitpoints, busy = 1})
At the INGAME.GUISCRIPT it will receive the message with a code like this:
The trick is to clone the “handmade” bars.
Now there are several important steps to do:
- Set them to the right layers to prevent the call-explosion (I’ve needed weeks to check that why I had 170 drawcalls and got it to this point as I was new to defold/lua)
- give every GUI a UNIQUE Id to pick and update them later!
- and of cause give each bar the right “value”
And… of cause the is a way to delete the bars if the unit has been destroyed. Also “called” with a message from the UNIT.SCRIPT
-- UNIT-BARS
if message_id == hash("unit_bar") then
-- create a new one?
if message.create == true then
-- New unit-bars? Clone templates
local newHealth = gui.clone(gui.get_node("unit_bar_health"))
local newEnergy = gui.clone(gui.get_node("unit_bar_energy"))
local newBusy = gui.clone(gui.get_node("unit_bar_busy"))
-- set them to the right layer (better for drawcalls and performance)
gui.set_layer(newHealth, "box")
gui.set_layer(newEnergy, "box")
gui.set_layer(newBusy, "box")
-- give them a unique-id
gui.set_id(newHealth, "unit_bar_health_" .. message.unitid)
gui.set_id(newEnergy, "unit_bar_energy_" .. message.unitid)
gui.set_id(newBusy, "unit_bar_busy_" .. message.unitid)
-- store them into the unitbars table
if newHealth and newEnergy and newBusy then
table.insert(unitbars, {unitid = message.unitid, pos = message.pos, healthnode = newHealth, health = message.health, energynode = newEnergy, energy = message.energy, busynode = newBusy, busy = message.busy})
end
--print("Unit-bar created for " .. message.unitid .. " healthid " .. tostring(gui.get_id(newHealth)) .. " energyid " .. tostring(gui.get_id(newEnergy)) .. " busyid " .. tostring(gui.get_id(newBusy)))
--print(" - VALUES: energy=" .. message.energy .. " health=" .. message.health .. " busy=" .. message.busy)
end
-- update bar - infos
for i,v in ipairs(unitbars) do
if unitbars[i].unitid == message.unitid then
-- do we have to remove?
if message.remove then
--print("INGAMEGUI: unitbar: removed from list: " .. message.unitid)
gui.delete_node(unitbars[i].healthnode)
gui.delete_node(unitbars[i].energynode)
gui.delete_node(unitbars[i].busynode)
table.remove(unitbars, i)
break
-- update unit-bar-infos
else
--print("INGAMEGUI: unitbar-update for " .. message.unitid .." hp=" .. message.health .. " nrg=" .. message.energy)
unitbars[i].pos = message.pos
unitbars[i].health = message.health
unitbars[i].energy = message.energy
unitbars[i].busy = message.busy
end
end
end
end
To update the bars there are a simple line at the UPDATE()-function in the UNIT.SCRIPT . Called every second:
-- UPDATING Unit-Bar
msg.post("main:/ingamegui#ingame", "unit_bar", {
unitid = go.get_id(), pos = self.pos + vmath.vector3(-16, 16, 0),
energy = GLOBAL.TILESIZE / self.unit.energyMax * self.unit.energy,
health = GLOBAL.TILESIZE / self.unit.hitpointsMax * self.unit.hitpoints,
busy = GLOBAL.TILESIZE / self.unit.ammoReloadSpeed * self.reloadTimer})