local options = { reverse_projection = false, hpbar = { bg = 0x13131355, fg = 0xef787878, txt = 0xffffffff } } local function entityBox(ent) local cube = canvas3d.addBox(ent.x - 0.25, ent.y - 0.25, ent.z - 0.25) local hpbar = canvas3d.addFrame({ ent.x - 0.25, ent.y + 0.25, ent.z - 0.25 }) cube.setAlpha(0x20) cube.setDepthTested(false) hpbar.setDepthTested(false) local hp_rect_bg, hp_rect_fg if ent.health ~= nil then hp_rect_bg = hpbar.addRectangle(0, 0, 100, 15, options.hpbar.bg) hp_rect_fg = hpbar.addRectangle(0, 0, 0, 15, options.hpbar.fg) end local hp_txt = hpbar.addText({ 0, 2 }, ent.name, options.hpbar.txt) return { _cube = cube, _hpbar = hpbar, _hp_rect_bg = hp_rect_bg, _hp_rect_fg = hp_rect_fg, _hp_txt = hp_txt, update = function(self, entity) self._cube.setPosition(entity.x - 0.25, entity.y - 0.25, entity.z - 0.25) self._hpbar.setPosition(entity.x, entity.y + 0.5, entity.z) if self._hp_rect_fg ~= nil then self._hp_rect_fg.setSize(100 * entity.health / entity.maxHealth, 15) end if entity.health ~= nil then self._hp_txt.setText(string.format("%s (%.1f/%.1f)", entity.name, entity.health, entity.maxHealth)) else self._hp_txt.setText(string.format("%s", entity.name)) end end, destroy = function(self) self._cube.remove() self._hpbar.remove() end } end return function() local cache = {} while _G._running do for uuid in table.keys(cache) do if surroundings.entitiesByUUID[uuid] == nil then cache[uuid]:destroy() cache[uuid] = nil end end for uuid, entity in pairs(surroundings.entitiesByUUID) do if uuid == player.id then -- nothing elseif cache[uuid] == nil then cache[uuid] = entityBox(entity) else cache[uuid]:update(entity) end end os.sleep(0.05) end for uuid in table.keys(cache) do cache[uuid]:destroy() end end