Hi everyone. I’m having trouble creating a smooth and accurate XP/Level bar with a GUI element. I have a functional module script that handles adding and subtracting XP and leveling logic. However, when I try to reflect this on my frame bar (top left in the video), the yellow progress bar doesn’t align correctly with actual stored XP numbers (the numbers inside the yellow frame are accurate). At first, tweeting seems fine, but after repeatedly adding XP and leveling up, the frame’s size becomes inaccurate.
I also store the remainder of XP after a level-up, which likely contributes to the inconsistency. I tried rounding the values using various math formulas, but the problem persists. The code might be messy, and I’m not sure how to fix it.
Does anyone have any suggestions for solving this?
– The Tweening Script:
local Players = game:GetService("Players")
local player = Players.LocalPlayer or Players.PlayerAdded
local playerGUI = player.PlayerGui
local levelXPGUI = playerGUI:WaitForChild("LevelXPGUI")
local blankLVLBar = levelXPGUI.BlankLVLBar
local progressBar = blankLVLBar.ProgressLVLBar
local TweenService = game:GetService("TweenService")
local RS = game:GetService("ReplicatedStorage")
local XPMod = require(RS.Modules.XPDistribution)
local XPModRemote = RS.XPModRemote
local defaultColor = progressBar.BackgroundColor3
local defaultColorBlank = blankLVLBar.BackgroundColor3
local xpGainSound = workspace.pick_up2
local LevelUpSound = workspace.LevelUp
local choir = workspace["Swinging Holiday"]
local yes = workspace.yeS
progressBar.Text = " XP: " .. 0 .."/"..200
local function TweenLVL(amount, MAX_XP_NEXT, currentStats, updatedStats, CURRENT_MAX)
local xpRemainder = 0
local currentXP = currentStats.CurrentXP
local updatedXP = updatedStats.CurrentXP
print(updatedXP .. " test2")
local currentWidthScale = progressBar.Size.X.Scale
print(amount .. " XP added")
xpGainSound:Play()
if MAX_XP_NEXT >= 617870 or CURRENT_MAX >= 617870 then
print(MAX_XP_NEXT .. CURRENT_MAX .. " LIMIT")
return
end
progressBar.Text = " XP: " .. updatedXP .."/"..MAX_XP_NEXT
local change = amount/CURRENT_MAX
change = math.floor(change * 10^3 + 0.5) / 10^3
print(change .. "change")
local newWidthScale = currentWidthScale + change
newWidthScale = math.floor(newWidthScale * 10^3 + 0.5) / 10^3
print(newWidthScale .. "new")
local targetColor = Color3.new(0.0901961, 1, 0.498039)
local targetColorBlank = Color3.new(0.0901961, 1, 0.498039)
while newWidthScale >= 1 do
xpRemainder = newWidthScale - 1
xpRemainder = math.floor(xpRemainder * 10^3 + 0.5) / 10^3
newWidthScale = 0
newWidthScale = xpRemainder + newWidthScale
local tweenColorInfoBlank = TweenInfo.new(.15, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local tweenColorBlank = TweenService:Create(blankLVLBar, tweenColorInfoBlank, {BackgroundColor3 = targetColorBlank})
tweenColorBlank:Play()
tweenColorBlank.Completed:Connect(function()
local revertTweenBlank = TweenService:Create(blankLVLBar, tweenColorInfoBlank, {BackgroundColor3 = defaultColorBlank})
revertTweenBlank:Play() -- Play the revert tween
end)
print(newWidthScale)
LevelUpSound:Play()
choir:Play()
yes:Play()
end
local targetSize = UDim2.new(newWidthScale, 0, 1, 0)
local tweenInfo = TweenInfo.new(.5, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out)
local tweenColorInfo = TweenInfo.new(.2, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local tween = TweenService:Create(progressBar, tweenInfo, {Size = targetSize})
local tweenColor = TweenService:Create(progressBar, tweenColorInfo, {BackgroundColor3 = targetColor})
tween:Play()
tweenColor:Play()
tweenColor.Completed:Connect(function()
local revertTween = TweenService:Create(progressBar, tweenColorInfo, {BackgroundColor3 = defaultColor})
revertTween:Play()
end)
print("XP Remainder:", xpRemainder)
end
XPModRemote.OnClientEvent:Connect(TweenLVL)
– Table from my module with XP required for each level:
local sculptingMastery = {
{Level = "Noobie", XP = 0},
{Level = "Beginner", XP = 200},
{Level = "Novice", XP = 375},
{Level = "Rookie", XP = 600},
{Level = "Apprentice", XP = 960},
{Level = "Skilled", XP = 1600},
{Level = "Adept", XP = 2720},
{Level = "Journeyman", XP = 4760},
{Level = "Expert", XP = 8600},
{Level = "Master", XP = 16340},
{Level = "Grandmaster", XP = 31860},
{Level = "Legendary", XP = 63790},
{Level = "Mythical", XP = 130770},
{Level = "Divine", XP = 274610},
{Level = "Transcendent", XP = 617870},
}
Server Script where I actually add XP to the player (xpAmount += 100) and pass arguments for the tween, each time after I finish the “sculpting action”:
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local DSS = game:GetService("DataStoreService")
local XPModRemote = RS.XPModRemote
local XPMod = require(RS.Modules.XPDistribution)
Players.PlayerAdded:Connect(function(player)
XPMod.newLevel(player)
end)
XPModRemote.OnServerEvent:Connect(function(plr, check)
if not plr then
warn("Player not found")
return
end
if not check then
warn("Check value not received")
return
end
local xpAmount = 0
if plr and check then
print(plr, check)
xpAmount += 100
local CURRENT_MAX = XPMod:XPTillNextLevel(plr)
local currentStats = XPMod:GetLevel(plr)
XPMod:AddXP(plr, xpAmount)
local updatedStats = XPMod:GetLevel(plr)
local MAX_XP_NEXT = XPMod:XPTillNextLevel(plr)
XPModRemote:FireClient(plr, xpAmount, MAX_XP_NEXT, currentStats, updatedStats, CURRENT_MAX)
end
if not plr then
print("problem transferring xp - Player Not Found")
return
end
if not check then
print("problem transferring xp - Sculpt finish check wasn't received")
return
end
end)