Physical progress bar leaving it's "boundaries" before shrinking back down

I have an xp/level system in my game where if your xp exceeds the level requirement, level goes up by 1 and the leftover xp overflows to the progress for the next level. The progress bar for the level is a physical part that changes size/position based on xp/xp requirement.
The problem is that after getting enough xp, the part leaves the xp bar for a split second before moving back into place, and i’m unsure how to fix that, any help?
Also sorry for the messy/scuffed code.

Video of the issue:

Code for changing the part’s size/position:

Code for the levelling up/changing xp value itself: (dont mind the comment)
Zrzut ekranu 2024-07-27 132413

1 Like

Oh btw heres the code in code blocks

local xp = game.ReplicatedStorage.XpCurrency
local xpReq = game.ReplicatedStorage.XpRequirement

local NumberConverter = require(game.ReplicatedStorage.SuffixHelper)

local currentXp = game.Players.LocalPlayer:WaitForChild("XpNV")
local currentXpReq = game.Players.LocalPlayer:WaitForChild("XpReqNV")

script.Parent.Text = tostring(NumberConverter.changingnotation(currentXp.Value)) .. "/" .. tostring(NumberConverter.changingnotation(currentXpReq.Value)) .. " XP"

local TweenService = game:GetService("TweenService")
local part = game.Workspace:WaitForChild("XpBar")
local currentSize = part.Size.X
local desiredSize = currentXp.Value / currentXpReq.Value * 29

local deltaSize = desiredSize - currentSize

local tweenInfo = TweenInfo.new(0)
local props = {
	Size = part.Size + Vector3.FromAxis(Enum.Axis.X)*deltaSize,
	Position = part.Position + Vector3.FromNormalId(Enum.NormalId.Left)*deltaSize/2.8  + Vector3.FromNormalId(Enum.NormalId.Front)*deltaSize/2.8
}

local tween = TweenService:Create(part, tweenInfo, props)
tween:Play()



currentXp.Changed:Connect(function()
	script.Parent.Text = tostring(NumberConverter.changingnotation(currentXp.Value)) .. "/" .. tostring(NumberConverter.changingnotation(currentXpReq.Value)) .. " XP"
	
	local TweenService = game:GetService("TweenService")
	local part = game.Workspace.XpBar
	local currentSize = part.Size.X
	local desiredSize = currentXp.Value / currentXpReq.Value * 29

	local deltaSize = desiredSize - currentSize

	local tweenInfo = TweenInfo.new(0)
	local props = {
		Size = part.Size + Vector3.FromAxis(Enum.Axis.X)*deltaSize,
		Position = part.Position + Vector3.FromNormalId(Enum.NormalId.Left)*deltaSize/2.8  + Vector3.FromNormalId(Enum.NormalId.Front)*deltaSize/2.8

	}

	local tween = TweenService:Create(part, tweenInfo, props)
	tween:Play()
end)
RemoteLevelUp.OnServerEvent:Connect(function(plr)
	local profile = DataHandler:getProfile(plr)
	
	if profile.Data["Xp"] >= profile.Data["XpReq"] then
		profile.Data["Xp"] -= profile.Data["XpReq"]
		profile.Data["Level"] += 1
		profile.Data["LevelSandMulti"] = 1.1 ^ (profile.Data["Level"] - 1)
		--sandstoneEffect.Value = level.Value
		profile.Data["XpReq"] = 10 * profile.Data["Level"]
		MultiCalculator:CalculateSandMulti(plr)
	end
end)```
1 Like

I recommend you replacing the physical bar with a UI element as it’s easier to work with, without a need to move the position and just the size.
For your solution though, you have to use math.clamp for both the size and position

where exactly do i use math.clamp here?

if i use it in the “props” local and apply it to size, it says the first argument is a vector3 when it expected a number

You’d have to use the bars “length” axis by doing Vector3.AXIS
for example, Vector3.Y returns the height of the part.