Is it possible to split Health into variables?

I haven’t made any code yet but I have an HP/POINT Display UI which shows the player their HP, The hp is only set at 3 digits max 100-999, So I was wondering is it possible to split up a players hp into variables?
Like for example
local HP 1 = the ones
local HP 2 = the tens
local HP 3 = the hundreds


Help would be greatly appreciated thank you!, I’m mainly asking as I am using a custom font as images unless you are able to import fonts into roblox?

2 Likes

You can convert it to a string and pull out the characters!

First solution, I don't think it's what you want
local h1, h2, h3 = tostring(health):match("(%d)(%d?)(%d?)")

Note that the resulting h1, h2, and h3 are in string format, but I think that’s what you want because it looks like you’re setting the Text property of a TextLabel anyway, which takes a string.

For numbers shorter than 3 digits, h3 and h2 could be nil. In those cases, you can do something like

label1.Text = h1
label2.Text = h2 or "0"
label3.Text = h3 or "0"

Results:

health = 789
h1: 7
h2: 8
h3: 9

health = 12
h1: 1
h2: 2
h3: nil

health = 5
h1: 5
h2: nil
h3: nil

To set unspecified numbers to 0 instead of nil (and have leading digits be 0, which I think you want), can go for something like:

local h1, h2, h3 = string.format("%03d", health):match("(%d)(%d?)(%d?)")

Results:

health = 789
h1: 7
h2: 8
h3: 9

health = 12
h1: 0
h2: 1
h3: 2

health = 5
h1: 0
h2: 0
h3: 5

4 Likes

Could use string.split(tostring(534), “”) which returns a table that is {5, 3, 4}. Of course those are strings but you can just convert them back to a number with tonumber if needed.

2 Likes

Yes this is what I want but cause I am using a custom font, am I able to list the strings as like hp1 hp2 hp3 and see what they are then make those the id of the imagelabel?

1 Like

Like if I do something like this for example.

local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

while wait() do
	local health = game.Players.LocalPlayer.Character.Humanoid.Health
	local h1, h2, h3 = string.format("%03d", health):match("(%d)(%d?)(%d?)")
	if h1 == "0" then
		hp1.Image = "rbxassetid://9935112439"
	end;
end;

Would that work?

1 Like

Assuming this is a local script, for efficiency and strain on the client I would only change the Health Gui when the Player’s Health changes.

Something like this:

local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

local player = game:GetService("Players").LocalPlayer
local humanoid = player.Character:WaitForChild("Humanoid")

local function CheckNumber(num, ui)
	if num == "0" then
		ui.Image = "rbxassetid://9935112439"
	end
	-- Repeat above if statement for each number
end

humanoid.HealthChanged:Connect(function (health)
	local h1, h2, h3 = string.format("%03d", math.round(health)):match("(%d)(%d?)(%d?)")
	CheckNumber(h1, hp1)
	CheckNumber(h2, hp2)
	CheckNumber(h3, hp3)
end)

Definitely more elegant solutions to this, but this should work and be less computing for the client.

2 Likes
local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

local player = game:GetService("Players").LocalPlayer
local humanoid = player.Character:WaitForChild("Humanoid")

local function CheckNumber(num, ui)
	if num == "0" then
		ui.Image = "rbxassetid://9935112439"
	elseif num =="1" then
		ui.Image = "rbxassetid://9935111928"
	elseif num =="2" then
		ui.Image = "rbxassetid://9935107204"
	elseif num =="3" then
		ui.Image = "rbxassetid://9935106762"
	elseif num =="4" then
		ui.Image = "rbxassetid://9935106143"
	elseif num =="5" then
		ui.Image = "rbxassetid://9935102544"
	elseif num =="6" then
		ui.Image = "rbxassetid://9935101238"
	elseif num =="7" then
		ui.Image = "rbxassetid://9935100690"
	elseif num =="8" then
		ui.Image = "rbxassetid://9935100133"
	elseif num =="9" then
		ui.Image = "rbxassetid://9935099305"
	end
end

humanoid.HealthChanged:Connect(function (health)
	local h1, h2, h3 = string.format("%03d", math.round(health)):match("(%d)(%d?)(%d?)")
	CheckNumber(h1, hp1)
	CheckNumber(h2, hp2)
	CheckNumber(h3, hp3)
end)

I’ve done this but it doesn’t seem to work is it cause I am using elseif?

1 Like

Doesn’t work in what way? Is it erroring?

2 Likes

No it just doesn’t change the ID, And the numbers on the actual UI turn invisible?, I’ll try if

1 Like

Now using if it doesn’t change the ID

local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

local player = game:GetService("Players").LocalPlayer
local humanoid = player.Character:WaitForChild("Humanoid")

local function CheckNumber(num, ui)
	if num == "0" then
		ui.Image = "rbxassetid://9935112439"
	if num =="1" then
		ui.Image = "rbxassetid://9935111928"
	if num =="2" then
		ui.Image = "rbxassetid://9935107204"
	if num =="3" then
		ui.Image = "rbxassetid://9935106762"
	if num =="4" then
		ui.Image = "rbxassetid://9935106143"
	if num =="5" then
		ui.Image = "rbxassetid://9935102544"
	if num =="6" then
		ui.Image = "rbxassetid://9935101238"
	if num =="7" then
		ui.Image = "rbxassetid://9935100690"
	if num =="8" then
		ui.Image = "rbxassetid://9935100133"
	if num =="9" then
		ui.Image = "rbxassetid://9935099305"
	end
end

humanoid.HealthChanged:Connect(function (health)
	local h1, h2, h3 = string.format("%03d", math.round(health)):match("(%d)(%d?)(%d?)")
	CheckNumber(h1, hp1)
	CheckNumber(h2, hp2)
	CheckNumber(h3, hp3)
end)
end
end
end
end
end
end
end
end
end
1 Like
local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

local player = game:GetService("Players").LocalPlayer
local humanoid = player.Character:WaitForChild("Humanoid")

local function CheckNumber(num, ui)
	if num == "0" then
		ui.Image = "rbxassetid://9935112439"
	end
	if num =="1" then
		ui.Image = "rbxassetid://9935111928"
	end
	if num =="2" then
		ui.Image = "rbxassetid://9935107204"
	end
	if num =="3" then
		ui.Image = "rbxassetid://9935106762"
	end
	if num =="4" then
		ui.Image = "rbxassetid://9935106143"
	end
	if num =="5" then
		ui.Image = "rbxassetid://9935102544"
	end
	if num =="6" then
		ui.Image = "rbxassetid://9935101238"
	end
	if num =="7" then
		ui.Image = "rbxassetid://9935100690"
	end
	if num =="8" then
		ui.Image = "rbxassetid://9935100133"
	end
	if num =="9" then
		ui.Image = "rbxassetid://9935099305"
		end
	end

humanoid.HealthChanged:Connect(function(health)
	local h1, h2, h3 = string.format("%03d", math.round(health)):match("(%d)(%d?)(%d?)")
	CheckNumber(h1, hp1)
	CheckNumber(h2, hp2)
	CheckNumber(h3, hp3)
end)

This still doesn’t work it just appears empty whenever the player gets damaged…, I’m extremely confused
https://gyazo.com/31086e7161eda32b90a398567fce7ead

1 Like
  1. Be sure those images are correct, because I can’t load them myself. If you put them as the image of a decal do they show up correctly, and are they the same ID in the decal as they are in your script?

  2. Your character might be loaded when the script runs yet, try

    local player = game.Players.LocalPlayer
    local character = player.Character or player.CharacterAdded:Wait()
    local humanoid = player.Character:WaitForChild("Humanoid")
    
  3. Ensure the digits are actually being calculated correctly by adding a print(h1, h2, h3)

  4. You can use a lookup table instead of the big if statement:

    local DIGITS = {
    	["0"] = "rbxassetid://9935112439",
    	["1"] = "rbxassetid://9935111928",
    	["2"] = "rbxassetid://9935107204",
    	["3"] = "rbxassetid://9935106762",
    	["4"] = "rbxassetid://9935106143",
    	["5"] = "rbxassetid://9935102544",
    	["6"] = "rbxassetid://9935101238",
    	["7"] = "rbxassetid://9935100690",
    	["8"] = "rbxassetid://9935100133",
    	["9"] = "rbxassetid://9935099305",
    }
    

    Then you just do e.g. hp1.Image = DIGITS[h1]

  5. (optional) You could use math, instead of string matching. If string matching works for you go for it though.

    local function GetDigits(number)
    	return {
    		Ones = math.floor(number) % 10,
    		Tens = math.floor(number / 10) % 10,
    		Hundreds = math.floor(number / 100) % 10
    	}
    end
    
    

Putting all those suggestions together:

local hp1 = script.Parent.Health.NoobHealthGUI.HP1
local hp2 = script.Parent.Health.NoobHealthGUI.HP2
local hp3 = script.Parent.Health.NoobHealthGUI.HP3

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local DIGITS = {
	[0] = "rbxassetid://9935112439",
	[1] = "rbxassetid://9935111928",
	[2] = "rbxassetid://9935107204",
	[3] = "rbxassetid://9935106762",
	[4] = "rbxassetid://9935106143",
	[5] = "rbxassetid://9935102544",
	[6] = "rbxassetid://9935101238",
	[7] = "rbxassetid://9935100690",
	[8] = "rbxassetid://9935100133",
	[9] = "rbxassetid://9935099305",
}

local function GetDigits(number)
	return {
		Ones = math.floor(number) % 10,
		Tens = math.floor(number / 10) % 10,
		Hundreds = math.floor(number / 100) % 10
	}
end

local function UpdateHealthGui(health)
	local digits = GetDigits(health)
	hp1.Image = DIGITS[digits.Hundreds]
	hp2.Image = DIGITS[digits.Tens]
	hp3.Image = DIGITS[digits.Ones]
	print(digits.Hundreds, digits.Tens, digits.Ones)
end

UpdateHealthGui(humanoid.Health)
humanoid.HealthChanged:Connect(UpdateHealthGui)

That works for me—the print, anyways. The images don’t load for me but I can’t really help that, check that your IDs are right.

3 Likes

If everything is correct now, it should work. (I didn’t test this on studio)

local HP_1 = script.Parent.Health.NoobHealthGUI.HP1
local HP_2 = script.Parent.Health.NoobHealthGUI.HP2
local HP_3 = script.Parent.Health.NoobHealthGUI.HP3

local Player = game.Players.LocalPlayer
local Humanoid = Player.Character:WaitForChild("Humanoid")

local NumbersImages = {
	"rbxassetid://9935112439",
	"rbxassetid://9935111928",
	"rbxassetid://9935107204",
	"rbxassetid://9935106762",
	"rbxassetid://9935106143",
	"rbxassetid://9935102544",
	"rbxassetid://9935101238",
	"rbxassetid://9935100690",
	"rbxassetid://9935100133",
	"rbxassetid://9935099305",
}

local function UpdateNumber(HP, ImageID)
    if HP == "1" then
        HP_1.Image = ImageID
    elseif HP == "2" then
        HP_2.Image = ImageID
    elseif HP == "3" then
        HP_3.Image = ImageID
    end
end

Humanoid.HealthChanged:Connect(function(Health)
    local NumbersTable: table = string.split(tostring(Health), "")
    
    for i, number in pairs(NumbersTable) do
        local ImageID = nil
        
        if not number == "0" then
            local ImageID = NumbersImages[tonumber(number)]
        else
            local ImageID = NumbersImages[10]
        end
        
        UpdateNumber(i, ImageID)
    end
end)

Also the number 0 image id is in last.

2 Likes

This doesn’t seem to work for me at all either… I’ll try the one the person above you posted.

1 Like

This works, albeit a bit ugly:

--!strict

local Players = game:GetService("Players")
local digitGuiContainer = script.Parent.Health.NoobHealthGUI

local DIGIT_GUI_PREFIX = "HP"
local ASSET_PREFIX = "rbxassetid://"
local MAX_NUM_DIGITS = 3

local digitImages = {
	"9935112414",
	"9935111915",
	"9935107197",
	"9935106743",
	"9935106123",
	"9935102514",
	"9935101225",
	"9935100674",
	"9935100121",
	"9935099243",
}

local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local function updateHealthGui(health)
	local healthString = tostring(health)

	for i = 1, MAX_NUM_DIGITS do
		local digitGuiName = DIGIT_GUI_PREFIX .. (MAX_NUM_DIGITS - i + 1)
		local digitGui = digitGuiContainer:FindFirstChild(digitGuiName)
		assert(digitGui, "Couldn't find digit gui " .. digitGuiName)
		
		local digitString = healthString:sub(-i, -i) ~= "" and healthString:sub(-i, -i) or "0"

		digitGui.Image = ASSET_PREFIX .. digitImages[tonumber(digitString) + 1]
	end
end

updateHealthGui(humanoid.Health)
humanoid.HealthChanged:Connect(updateHealthGui)

3 Likes

It kinda works?
https://gyazo.com/0cc3767ecfc1f950d69c0a42a10f3388
But I have a poison script in my game which probably messes around with it alot? It results in no error so I’ll quickly remove the poison script and see.
Edit : It’s not the poison script it happens when regenerating health aswell?
https://gyazo.com/54d0c5f71fb0938302509b5f71a81220

1 Like

Could you show what the player’s health is changing to in yhe humanoid’s properties? It could be that your other scripts are changing the health improperly.

If thats not the issue maybe check that all your image files are set to the correct place in the table digitImages table.

2 Likes

I think it’s just natural roblox regen I dont think it does ones tens and hundreds but also counts the decimels

1 Like

Ohh! Good point! You could try rounding the health before passing it into the updateHeathGui function.

updateHealthGui(math.round(humanoid.Health))
humanoid.HealthChanged:Connect(updateHealthGui)
2 Likes

This doesn’t even make sense??
https://gyazo.com/2a5b8e0bf849656dbcf3d92c94c8c476
The values aren’t even equal… Unless there’s a way to round humanoid health too?
https://gyazo.com/c01965e4c0f7cf2ba7cc348c2c0131b3
Yeah I gotta somehow round humanoid health.

--!strict

local Players = game:GetService("Players")
local digitGuiContainer = script.Parent.Health.NoobHealthGUI

local DIGIT_GUI_PREFIX = "HP"
local ASSET_PREFIX = "rbxassetid://"
local MAX_NUM_DIGITS = 3

local digitImages = {
	"9935112414",
	"9935111915",
	"9935107197",
	"9935106743",
	"9935106123",
	"9935102514",
	"9935101225",
	"9935100674",
	"9935100121",
	"9935099243",
}

local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local function updateHealthGui(health)
	local healthString = tostring(health)

	for i = 1, MAX_NUM_DIGITS do
		local digitGuiName = DIGIT_GUI_PREFIX .. (MAX_NUM_DIGITS - i + 1)
		local digitGui = digitGuiContainer:FindFirstChild(digitGuiName)
		assert(digitGui, "Couldn't find digit gui " .. digitGuiName)

		local digitString = healthString:sub(-i, -i) ~= "" and healthString:sub(-i, -i) or "0"

		digitGui.Image = ASSET_PREFIX .. digitImages[tonumber(digitString) + 1]
	end
end

updateHealthGui(math.round(humanoid.Health))
humanoid.HealthChanged:Connect(updateHealthGui)

Still no dice why this doesn’t work…