UI Module Stops Working After Respawn

Hi. I have this issue where when I respawn my module code that controls the GUI just breaks I can still use connections but it is not refreshing or going though that debug I added.

-Main

local Framework = {}
Framework.__index = Framework

-- Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local StarterGUI = game:GetService("StarterGui")
local TweenService = game:GetService("TweenService")
local Lighting = game:GetService("Lighting")
local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AnimationsLib = require(game:GetService("ReplicatedStorage"):WaitForChild("Assets"):WaitForChild("Modules"):WaitForChild("ClientModules"):WaitForChild("AnimationLibrary")):getAnimations()
local TweenModule = require(ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Modules"):WaitForChild("UniversalModules"):WaitForChild("TweenModule"))
local Maid = require(script:WaitForChild("Maid"))
local ColourSequencingModule = require(ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Modules"):WaitForChild("UserInterface"):WaitForChild("ColourSequence"))
--local Screen3DGenModule = require(ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Modules"):WaitForChild("UserInterface"):WaitForChild("Screen3D"))
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")

local Packets = require(ReplicatedStorage:WaitForChild("Assets").Modules.Networking.Packets)

local Assets = ReplicatedStorage:WaitForChild("Assets")
local PlayerAssets = ReplicatedStorage:WaitForChild("PlayerAssets")
local Events = Assets.Events

local MobileActionHandler = require(Assets.Modules.ClientModules.MobileActionHandler)
local DownedActionFrame = MobileActionHandler:CreateFrame("DownedActionFrame", "DownedButtons", false)
local DownedReviveButtonLoaded = false

local Player : Player = Players.LocalPlayer
local Character : Model = nil
local Humanoid : Humanoid = nil

local PlayerData = Player:WaitForChild("Data", 5)
local Leaderstats = Player:WaitForChild("leaderstats")	

local PlayerGui = Player.PlayerGui
local PlayerScripts = Player.PlayerScripts

local Mouse = Player:GetMouse()

local UIElements = {
	GameUI = nil,
	PlayerStats = nil,
	Hotbar = nil,
	Menu = nil,
}

UIElements.GameUI = PlayerGui:WaitForChild("GameUI")
local mainFrame = UIElements.GameUI:WaitForChild("MainFrame")

UIElements.Menu = PlayerGui:WaitForChild("MenuUI")
local menuFrame = UIElements.Menu:WaitForChild("MainFrame")

UIElements.PlayerStats = {
	Frame = mainFrame:FindFirstChild("PlayerStatsFrame"),
	DownedText = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("DownedText"),

	Health = {
		Frame = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("PlayerStatus"):FindFirstChild("HealthFrame"),
		Bar = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("PlayerStatus"):FindFirstChild("HealthFrame"):FindFirstChild("Bar"),
		Overlay = mainFrame:FindFirstChild("VisualEffectsFrame"):FindFirstChild("Health")
	},
	Stamina = {
		Frame = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("PlayerStatus"):FindFirstChild("StaminaFrame"),
		Bar = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("PlayerStatus"):FindFirstChild("StaminaFrame"):FindFirstChild("Bar"),
		Overlay = mainFrame:FindFirstChild("VisualEffectsFrame"):FindFirstChild("Stamina")
	},
	Downed = {
		Frame = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("DownedFrame"),
		Bar = mainFrame:FindFirstChild("PlayerStatsFrame"):FindFirstChild("Frame"):FindFirstChild("DownedFrame"):FindFirstChild("Bar"),
		Overlay = mainFrame:FindFirstChild("VisualEffectsFrame"):FindFirstChild("Downed")
	}

}

UIElements.DeathFrame = {
	Frame = mainFrame:FindFirstChild("DeathFrame"),
	RespawnButton = mainFrame:FindFirstChild("DeathFrame"):FindFirstChild("RespawnButton"),
	InfoFrame = mainFrame:FindFirstChild("DeathFrame"):FindFirstChild("InfoList"),
}
-- Hotbar
UIElements.Hotbar = {
	Frame = mainFrame:FindFirstChild("HotbarFrame"):FindFirstChild("MainFrame"),
	Contents = mainFrame:FindFirstChild("HotbarFrame"):FindFirstChild("MainFrame"):FindFirstChild("Contents"),
	Template = mainFrame:FindFirstChild("HotbarFrame"):FindFirstChild("MainFrame"):FindFirstChild("Contents"):FindFirstChild("Excluded"):FindFirstChild("BasicItem")
}

-- Menu UI Elements
UIElements.Menu = {
	Frame = menuFrame:FindFirstChild("MainMenuFrame"),

	CurrentFrameOpen = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("CurrentFrameOpen"),
	LastFrameOpen = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("LastFrameOpen"),

	Player = {
		ButtonsFrame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("ButtonsFrame"),
		CurrentFrameUI = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"),
		PlayerFrame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"),
		PlayerViewer = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"),
		PlayerModelViewport = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"):FindFirstChild("PlayerModel"),
		WorldModel = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"):FindFirstChild("PlayerModel"),
		PlayerNameFrame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"):FindFirstChild("PlayerNameFrame"),
		CharacterCFrameHeadValue = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"):FindFirstChild("PlayerModel"):FindFirstChild("Head"),
		CharacterCFrameBodyValue = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerViewport"):FindFirstChild("PlayerModel"):FindFirstChild("Body"),
	},

	Inventory = {
		Frame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("InventoryFrame"),
		Contents = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("InventoryFrame"):FindFirstChild("Contents"),
		WeaponList = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("InventoryFrame"):FindFirstChild("Contents"):FindFirstChild("WeaponList"),
		WeaponDetails = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("InventoryFrame"):FindFirstChild("Contents"):FindFirstChild("WeaponDetails"),
		Template = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("InventoryFrame"):FindFirstChild("Contents"):FindFirstChild("WeaponList"):FindFirstChild("ExampleButton"):FindFirstChild("WeaponButton"),
	},

	PlayerLevelStats = {
		Frame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerLevel"),
		PlayerDetails = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerLevel"):FindFirstChild("PlayerStatsDetails"),

		LevelXP = {
			Frame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerLevel"):FindFirstChild("levelBar"),
			Bar = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("MainCurrentFrameUI"):FindFirstChild("PlayerFrame"):FindFirstChild("PlayerLevel"):FindFirstChild("levelBar"):FindFirstChild("bar")
		}
	},

	Buttons = {
		Frame = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("ButtonsFrame"),
		PlayButton = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("ButtonsFrame"):FindFirstChild("PlayButton"),
		InvButton = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("ButtonsFrame"):FindFirstChild("InventoryButton"),
		HardcoreButton = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("ButtonsFrame"):FindFirstChild("HardcoreButton"),
		BackButton = menuFrame:FindFirstChild("MainMenuFrame"):FindFirstChild("BackButton"),
	},


}

-- Constructor
function Framework.new()
	local self = setmetatable({}, Framework)

	-- Setup
	self.Trove = require(ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Modules"):WaitForChild("UtilityModules"):WaitForChild("Trove"))
	self._Trove = self.Trove.new()

	self.MenuConnections = {}
	self.HasCreatedPlayerModel = false
	self.Inventory = {
		BackpackButtons = {},
		Connections = {}
	}
	self.Status = {
		InMenu = true,
		RobloxInventoryEnabled = false
	}

	self.GradieatedButtons = {}


	-- Initial character setup
	Character = Player.Character or Player.CharacterAdded:Wait()
	self:OnCharacterAdded(Character)

	--self:ToggleRobloxInventory(false)

	-- Reconnect on respawn
	Player.CharacterAdded:Connect(function(char)
		self:OnCharacterAdded(char)

		char.Destroying:Connect(function()
			self:Cleanup()
		end)
	end)

	-- Menu state change listener
	PlayerScripts.Values.Camera.IsInMenu.Changed:Connect(function()
		self.Status.InMenu = PlayerScripts.Values.Camera.IsInMenu.Value
		mainFrame.Visible = not self.Status.InMenu
		menuFrame.Visible = self.Status.InMenu
		Lighting.MenuBlur.Enabled = self.Status.InMenu
	end)

	-- Cleanup on leave
	Players.PlayerRemoving:Once(function(playerLeaving)
		if playerLeaving == Player then
			self:Cleanup()
		end
	end)
	
	if Player.Character then
		self:OnCharacterAdded(Player.Character)
	end


	return self
end

-- Called whenever a character spawns or respawns
function Framework:OnCharacterAdded(char)
	
	print("[Framework] OnCharacterAdded called for", char.Name)
	self._Trove:Clean()
	self._Trove = self.Trove.new()

	Character = char
	Humanoid = Character:WaitForChild("Humanoid")

	self:Initialize()

	Lighting.MenuBlur.Enabled = true
	self.Status.InMenu = true
	PlayerScripts.Values.Camera.IsInMenu.Value = self.Status.InMenu
	mainFrame.Visible = not self.Status.InMenu
	menuFrame.Visible = self.Status.InMenu

	self:RefreshUI()
end

-- Initialization
function Framework:Initialize()
	self:RefreshCharacterVariables()
	self:SetupUI()
	self:RefreshUI()
	--self:SetupInventorySystem()
end

function Framework:RefreshCharacterVariables()
	Character = Player.Character or Player.CharacterAdded:Wait()
	Humanoid = Character:WaitForChild("Humanoid")
end


function Framework:SetupUI()
	self:InitializeMenu()
	-- Initialize status bars

end

function Framework:InitializeMenu()
	Lighting.MenuBlur.Enabled = true
	
	UIElements.Menu.LastFrameOpen.Value = UIElements.Menu.Player.PlayerFrame
	UIElements.Menu.CurrentFrameOpen.Value = UIElements.Menu.Player.PlayerFrame

	UIElements.Menu.CurrentFrameOpen.Value.Visible = true

	if UIElements.Menu.CurrentFrameOpen.Value ~= UIElements.Menu.Player.PlayerFrame then
		UIElements.Menu.Buttons.BackButton.Visible = true
	else
		UIElements.Menu.Buttons.BackButton.Visible = false
	end

	self._Trove:Connect(UIElements.Menu.CurrentFrameOpen.Changed, function()
		UIElements.Menu.CurrentFrameOpen.Value.Visible = true
		UIElements.Menu.LastFrameOpen.Value.Visible = false

		if UIElements.Menu.CurrentFrameOpen.Value ~= UIElements.Menu.Player.PlayerFrame then
			UIElements.Menu.Buttons.BackButton.Visible = true
		else
			UIElements.Menu.Buttons.BackButton.Visible = false
		end
	end)


	task.spawn(function()
		for i, Items in UIElements.Menu.Frame:GetDescendants() do
			if game:GetService("CollectionService"):HasTag(Items, "CLEANUP") then
				Items:Destroy()
			end
		end

		if not Player:HasAppearanceLoaded() then
			Player.CharacterAppearanceLoaded:Wait()
		end


		Character.Archivable = true

		local CharacterClone = self._Trove:Clone(Character)
		CharacterClone:AddTag("CLEANUP")

		print("[FRAMEWORK_CLIENT]: CHARACTER INSTANCE - ".. CharacterClone.Name)
		CharacterClone:PivotTo(UIElements.Menu.Player.CharacterCFrameHeadValue.Value)
		CharacterClone.Parent = UIElements.Menu.Player.WorldModel
		if CharacterClone.Animate then
			CharacterClone.Animate.Idle.Value = true
		end


		UIElements.Menu.Player.PlayerNameFrame.PlayerName.Text = Player.DisplayName.." (@"..Player.Name..")"
		Events.GetShiftlock:Fire("Disable")

		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)



	end)

	self:InitializeMenuButtons()
end

function Framework:InitializeMenuButtons()

	if UserInputService.TouchEnabled then
		UIElements.Menu.Buttons.PlayButton.ListSpace.ToolTip.Text = "PRESS"
	elseif UserInputService.GamepadEnabled then
		UIElements.Menu.Buttons.PlayButton.ListSpace.ToolTip.Text = "BUTTON A"
	elseif UserInputService.KeyboardEnabled then
		UIElements.Menu.Buttons.PlayButton.ListSpace.ToolTip.Text = "SPACE"
	end

	Character:WaitForChild("Humanoid").JumpPower = 0

	local function playCode()
		Lighting.MenuBlur.Enabled = false
		Character:WaitForChild("Humanoid").RootPart.Anchored = false

		PlayerScripts:WaitForChild("Values").Camera.Focus.Value = Character:WaitForChild("Head")



		local weaponData = {
			"Melee",
			"war_axe"
		}
		--	Packets.PlayEvent:Fire(weaponData)

		self.Status.InMenu = false
		PlayerScripts.Values.Camera.IsInMenu.Value = self.Status.InMenu
		mainFrame.Visible = not self.Status.InMenu
		menuFrame.Visible = self.Status.InMenu

		Events.GetShiftlock:Fire("Enable")

		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
		Character:WaitForChild("Humanoid").JumpPower = 45
	end
	-- Implement menu button initialization logic here
	self.MenuConnections["PlayButton"] = self._Trove:Connect(UIElements.Menu.Buttons.PlayButton.MouseButton1Click, function()
		playCode()
	end)

	self.MenuConnections["BackButton"] = self._Trove:Connect(UIElements.Menu.Buttons.BackButton.MouseButton1Click, function()
		UIElements.Menu.CurrentFrameOpen.Value = UIElements.Menu.LastFrameOpen.Value
	end)

	self.MenuConnections["InventoryButton"] = self._Trove:Connect(UIElements.Menu.Buttons.InvButton.MouseButton1Click, function()
		UIElements.Menu.LastFrameOpen.Value = UIElements.Menu.CurrentFrameOpen.Value

		UIElements.Menu.CurrentFrameOpen.Value = UIElements.Menu.Inventory.Frame
	end)

	local conn = UserInputService.InputBegan:Connect(function(input, IsTyping)
		if IsTyping then return end
		if self.Status.InMenu == true then

			if (input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.ButtonA) then
				playCode()
			end
		end
	end)

	task.spawn(function()
		local key, Input = UserInputService.InputBegan:Wait()
		if key.KeyCode == Enum.KeyCode.Space or key.KeyCode == Enum.KeyCode.ButtonA then
			task.wait(0.5)
			conn:Disconnect()
			conn = nil
		end
	end)
end

function Framework:InitializeStatusBars()

	self:SetupPlayerMenuStats()

	self:UIStrokeConnection()

	self:UIButtonsConnection()

	self:SetupOverlays(UIElements.PlayerStats.Health.Overlay, UIElements.PlayerStats.Stamina.Overlay)

	self:SetupLevelXPBar(UIElements.Menu.PlayerLevelStats.LevelXP.Bar)
	-- Health bar setup
	self:SetupHealthBar(UIElements.PlayerStats.Health.Bar)
	-- Level XP bar setup
	-- Stamina bar setup
	self:SetupStaminaBar(UIElements.PlayerStats.Stamina.Bar)

	self:SetupDeathConnection(UIElements.DeathFrame.Frame, UIElements.DeathFrame.InfoFrame, UIElements.PlayerStats.Frame)

	self:SetupDownedConnections(UIElements.PlayerStats.Frame, UIElements.PlayerStats.Downed.Frame, UIElements.PlayerStats.Downed.Bar, UIElements.PlayerStats.DownedText)
	-- Colorize stamina bar after delay

end

function Framework:SetupDeathConnection(DeathFrame : CanvasGroup, DeathInfoFrame : CanvasGroup, PlayerStatsFrame : CanvasGroup)
	task.wait()

	local DeathConnection = nil

	DeathFrame.Position = UDim2.fromScale(0.5, 2)

	local DeathFrameTween : TweenBase = TweenModule:To(DeathFrame, {
		Position = UDim2.fromScale(0.5, 0.5)
	}, 0.2, TweenModule.EasingStyle.Sine, Enum.EasingDirection.InOut)

	local TransparencyTween : TweenBase = TweenModule:To(DeathFrame, {
		BackgroundTransparency = 0.35
	}, 0.5, TweenModule.EasingStyle.Cubic, TweenModule.EasingDirection.In)

	local PlayerValuesTween : TweenBase = TweenModule:To(PlayerStatsFrame, {
		GroupTransparency = 1	
	}, 1.5, TweenModule.EasingStyle.Circular, TweenModule.EasingDirection.Out)

	self._Trove:Connect(UIElements.DeathFrame.RespawnButton.MouseButton1Click, function()
		Packets.RespawnEvent:Fire()
	end)

	self._Trove:Connect(Humanoid.Died, function()
		if self.Status.InMenu == false then
			PlayerValuesTween:Play()
			DeathFrameTween:Play()
			DeathFrameTween.Completed:Connect(function()
				TransparencyTween:Play()
			end)

			DeathConnection = UserInputService.InputBegan:Connect(function(input, isTyping)
				if isTyping and self.Status.InMenu == true then return end
				if (input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.ButtonA) then
					if Humanoid.Health == 0 then
						Packets.RespawnEvent:Fire()
					end
				end
			end)


		else
			StarterGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, true)
			DeathFrameTween:Cancel()
			PlayerValuesTween:Cancel()
			DeathConnection:Disconnect()
			DeathConnection = nil
			DeathFrame.Position = UDim2.fromScale(0.5, 2)
			DeathFrame.Transparency = 1
			PlayerStatsFrame.GroupTransparency = 0
		end
	end)

end

function Framework:SetupDownedConnections(PlayerStatsFrame : CanvasGroup, DownedFrame : CanvasGroup, DownedBar : Frame, DownedText : TextLabel)
	local DownedMaxBar = 20
	local DownedValue = 0

	local Keybinds = Events.GetKeybinds:Invoke()
	local IncreaseConnection = nil

	local HasRevived = false
	local MobileIsReviving = false

	if UserInputService.TouchEnabled then
		DownedActionFrame:RecreateButtons("DownedButtons")

		DownedActionFrame:ButtonVisibility("all", false)

		DownedActionFrame:ConnectFrame("buttonadded", "Revive", function()
			DownedReviveButtonLoaded = true
		end)
	end

	self._Trove:Connect(Humanoid.AttributeChanged, function(attribute)

		if attribute == "Downed" then
			DownedValue = 0

			DownedActionFrame:ButtonVisibility("all", Humanoid:GetAttribute("Downed"))

			if IncreaseConnection then
				IncreaseConnection:Disconnect()
				IncreaseConnection = nil
			end

			IncreaseConnection = nil

			local tween2 = TweenModule:To(DownedFrame, {
				GroupTransparency = Humanoid:GetAttribute("Downed") and 0 or 1
			}, 0.5, TweenModule.EasingStyle.Quadratic, TweenModule.EasingDirection.InOut)

			tween2:Play()

			--[[local tween4 = TweenModule:To(PlayerStatsFrame.Frame.UIListLayout, {
				Padding = UDim.new((Humanoid:GetAttribute("Downed") and PlayerStatsFrame.Frame.DownedLayout or PlayerStatsFrame.Frame.AliveLayout), 0)
			}, 0.5, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.Out)

			tween4:Play()]]

			if Humanoid:GetAttribute("Downed") == true then
				DownedFrame.Visible = true

				task.spawn(function()
					while Humanoid:GetAttribute("Downed") == true do
						local Ratio = DownedValue / DownedMaxBar

						local tweenBar = TweenModule:To(DownedBar, {
							Size = UDim2.fromScale(Ratio, 1)
						}, 0.5, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.Out)

						tweenBar:Play()

						if DownedValue >= DownedMaxBar then
							if IncreaseConnection then
								IncreaseConnection:Disconnect()
								IncreaseConnection = nil
							end

							if Humanoid.Health > 0 then
								Packets.ReviveEvent:Fire()
								print("REVIVED")
								DownedValue = 0
								HasRevived = true
							end
						end
						task.wait(0.1)
					end
				end)

				local function ScriptFunctionStart()
					if IncreaseConnection then
						IncreaseConnection:Disconnect()
						IncreaseConnection = nil
					end

					if Humanoid:GetAttribute("Downed") == true then
						IncreaseConnection = self._Trove:Connect(RunService.Heartbeat, function(dt)
							if DownedValue < DownedMaxBar then
								DownedValue += dt * 2.75
								DownedValue = math.clamp(DownedValue, 0, DownedMaxBar)
							end
						end)
					else
						if IncreaseConnection then
							IncreaseConnection:Disconnect()
							IncreaseConnection = nil
						end
					end
				end

				local function ScriptFunctionEnd()
					if IncreaseConnection then
						IncreaseConnection:Disconnect()
						IncreaseConnection = nil
					end
					DownedValue = 0
				end

				local function isKeycode(obj)
					if typeof(obj) == "EnumItem" then
						return ({pcall(function()
							local x = Enum.KeyCode[obj.Name]
						end)})[1]
					else
						return false
					end
				end

				self._Trove:Connect(UserInputService.InputBegan, function(input, IsTyping)
					if IsTyping then return end


					if isKeycode(Keybinds["REVIVE"]) then
						if input.KeyCode == Keybinds["REVIVE"] then
							ScriptFunctionStart()
						end 
					else
						if input.UserInputType == Keybinds["REVIVE"] then
							ScriptFunctionStart()
						end
					end
				end)

				self._Trove:Connect(UserInputService.InputEnded, function(input, IsTyping)
					if IsTyping then return end



					if isKeycode(Keybinds["REVIVE"]) then
						if input.KeyCode == Keybinds["REVIVE"] then
							ScriptFunctionEnd()
						end
					else
						if input.UserInputType == Keybinds["REVIVE"] then
							ScriptFunctionEnd()
						end
					end
				end)

			else
				DownedValue = 0
			end

			DownedText.Visible = Humanoid:GetAttribute("Downed") or false
			DownedText.Text = "Press and hold "..Keybinds["REVIVE"].Name.." to revive yourself."

			if UserInputService.TouchEnabled then
				DownedText.Text = "Press and hold ".."'Revive'".." to revive yourself."
			end
		end
	end)


	if UserInputService.TouchEnabled then
		--if DownedReviveButtonLoaded == false then repeat task.wait(5) until DownedReviveButtonLoaded == true

		DownedActionFrame:Connect("Revive", "buttondown", function()
			if MobileIsReviving == false then
				MobileIsReviving = true
				DownedActionFrame:SetButtonState("Revive", "selected")


				if Humanoid:GetAttribute("Downed") == true then
					IncreaseConnection = self._Trove:Connect(RunService.Heartbeat, function(dt)
						if DownedValue < DownedMaxBar then
							DownedValue += dt * 2.75
							DownedValue = math.clamp(DownedValue, 0, DownedMaxBar)
						end
					end)
				else
					if IncreaseConnection then
						IncreaseConnection:Disconnect()
						IncreaseConnection = nil
					end

				end

			else
				MobileIsReviving = false

				DownedActionFrame:SetButtonState("Revive", "deselected")


				if IncreaseConnection then
					IncreaseConnection:Disconnect()
					IncreaseConnection = nil
				end
				DownedValue = 0
			end
		end)

	end

	Humanoid.Died:Connect(function()
		if IncreaseConnection then
			IncreaseConnection:Disconnect()
			IncreaseConnection = nil
		end
	end)
	--ContextActionService:BindAction("REVIVE", handleDowned, false, Keybinds["REVIVE"] or Enum.KeyCode.R)
end

function Framework:UIButtonsConnection()

	local IdleSequence = ColourSequencingModule:GetButtonIdleSequence()
	local HoverSequence = ColourSequencingModule:GetButtonHoverSequence()

	local function CleanUp()
		for _, Button in self.GradieatedButtons do
			if Button["OnHoverStart"] then
				Button["OnHoverStart"]:Disconnect()
				Button["OnHoverStart"] = nil
			end

			if Button["OnHoverEnd"] then
				Button["OnHoverEnd"]:Disconnect()
				Button["OnHoverEnd"] = nil
			end
		end
	end

	local function CreateGradientConnection(Button : GuiButton)
		self.GradieatedButtons[Button]["OnHoverStart"] = self._Trove:Connect(Button.MouseEnter, function()
			if Button:FindFirstChildOfClass("UIGradient") then
				Button:FindFirstChildOfClass("UIGradient").Color = HoverSequence
			end
		end)

		self.GradieatedButtons[Button]["OnHoverEnd"] = self._Trove:Connect(Button.MouseLeave, function()
			if Button:FindFirstChildOfClass("UIGradient") then
				Button:FindFirstChildOfClass("UIGradient").Color = IdleSequence
			end
		end)
	end

	local function Update()
		CleanUp()

		for _, BTN in game:GetService("CollectionService"):GetTagged("_HOVER_HANDLED") do
			if BTN:IsA("TextButton") or BTN:IsA("ImageButton") then
				if not self.GradieatedButtons[BTN] then
					self.GradieatedButtons[BTN] = {}
					CreateGradientConnection(BTN)
				else
					CreateGradientConnection(BTN)
				end
			end
		end
	end

	Update()

	self._Trove:Connect(PlayerGui.AncestryChanged, Update)	
	self._Trove:Connect(PlayerGui.DescendantAdded, Update)
	self._Trove:Connect(PlayerGui.DescendantRemoving, Update)
	self._Trove:Connect(PlayerGui.ChildAdded, Update)
	self._Trove:Connect(PlayerGui.ChildRemoved, Update)

end

function Framework:UIStrokeConnection()
	local StarterGUIDecendants = PlayerGui:GetDescendants()

	for i, UIStroke in pairs(StarterGUIDecendants) do
		if UIStroke:IsA("UIStroke") then
			if UIStroke.Parent:IsA("CanvasGroup") then
				local CanvasGroup = UIStroke.Parent

				self._Trove:Connect(CanvasGroup.Changed, function()
					UIStroke.Transparency = CanvasGroup.GroupTransparency
				end)
			end
		end	
	end
end

function Framework:SetupOverlays(HealthOverlay, StaminaOverlay)


	self._Trove:Connect(Humanoid.HealthChanged, function(newHealth)
		if self.Status.InMenu == false then
			local DownedState = Humanoid:GetAttribute("Downed")
			local maxHealth = DownedState and 110 or Humanoid.MaxHealth
			local healthPercentage = newHealth / maxHealth

			-- Show overlay only when health is 3/4 or less OR when downed
			if healthPercentage <= 0.65 or DownedState then
				local minTransparency = (DownedState and 0.2 or 0.5)
				local maxTransparency = 1

				-- Calculate target transparency (more visible at lower health)
				-- Maps health percentage 0-0.75 to transparency 0-1
				local normalizedHealth = math.clamp(healthPercentage / 0.65, 0, 1)
				local transparency = minTransparency + (normalizedHealth * (maxTransparency - minTransparency))

				local Tween = TweenModule:To(HealthOverlay, {
					ImageTransparency = transparency
				}, 0.5, TweenModule.EasingStyle.Quadratic, Enum.EasingDirection.InOut)

				Tween:Play()
			elseif healthPercentage > 0.65 then
				-- Health is above 75% and not downed - hide overlay
				local Tween = TweenModule:To(HealthOverlay, {
					ImageTransparency = 1  -- Fully transparent
				}, 0.5, TweenModule.EasingStyle.Quadratic, Enum.EasingDirection.InOut)

				Tween:Play()
			elseif DownedState then
				local Tween = TweenModule:To(HealthOverlay, {
					ImageTransparency = 0.2  -- Fully transparent
				}, 0.5, TweenModule.EasingStyle.Quadratic, Enum.EasingDirection.InOut)

				Tween:Play()
			end
		end
	end)

	self._Trove:Connect(Humanoid.AttributeChanged, function()
		if self.Status.InMenu == false then
			if Humanoid:GetAttribute("Stamina") then
				local DownedState = Humanoid:GetAttribute("Downed")
				local Stamina = Humanoid:GetAttribute("Stamina")
				local MaxStamina = Humanoid:GetAttribute("MaxStamina")

				local minTransparency = 0.1
				local maxTransparency = 1 

				local transparency = nil

				if DownedState == true then
					transparency = 0.5
				else
					transparency =  minTransparency + (Stamina / MaxStamina) * (maxTransparency - minTransparency)
				end

				local Tween = TweenModule:To(StaminaOverlay, {
					ImageTransparency = transparency
				}, 0.5, TweenModule.EasingStyle.Quadratic, Enum.EasingDirection.InOut)

				Tween:Play()
			end
		end
	end)


end

function Framework:SetupPlayerMenuStats()
	if PlayerData then

		local Kills = PlayerData:WaitForChild("Kills")
		local Deaths = PlayerData:WaitForChild("Deaths")
		local Assists = PlayerData:WaitForChild("Assists")
		local Level = Leaderstats:WaitForChild("Level")
		local KDR = PlayerData:WaitForChild("KDR")
		local XP = PlayerData:WaitForChild("LevelXP")
		local MaxXP = PlayerData:WaitForChild("MaxLevelXP")

		local function Update()
			UIElements.Menu.PlayerLevelStats.PlayerDetails.Kills:WaitForChild("Value").Text = Kills.Value
			UIElements.Menu.PlayerLevelStats.PlayerDetails.Deaths:WaitForChild("Value").Text = Deaths.Value
			UIElements.Menu.PlayerLevelStats.PlayerDetails.KDR:WaitForChild("Value").Text = KDR.Value
			UIElements.Menu.PlayerLevelStats.PlayerDetails.Assists:WaitForChild("Value").Text = Assists.Value
			UIElements.Menu.PlayerLevelStats.Frame.XPLevel.Text = XP.Value.."/"..MaxXP.Value
			UIElements.Menu.PlayerLevelStats.Frame.PlayerName.Text = Player.Name.." | Level "..Level.Value
		end

		Update()

		self._Trove:Connect(Kills.Changed, Update)
		self._Trove:Connect(Deaths.Changed, Update)
		self._Trove:Connect(KDR.Changed, Update)
		self._Trove:Connect(XP.Changed, Update)
		self._Trove:Connect(Assists.Changed, Update)
		self._Trove:Connect(MaxXP.Changed, Update)
	end
end

function Framework:SetupHealthBar(bar)
	if not bar then return end

	local OriginalColour = bar.BackgroundColor3

	bar.Size = UDim2.new(1, 0, 1, 0) -- Start full

	self._Trove:Connect(Humanoid.HealthChanged, function(currentHealth)
		local maxHealth = Humanoid.MaxHealth
		local ratio = currentHealth / maxHealth
		local tween = TweenModule:To(bar, {
			Size = UDim2.new(ratio, 0, 1, 0)
		}, 0.25, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.InOut)

		tween:Play()
	end)

	self._Trove:Connect(Humanoid.AttributeChanged, function()
		if Humanoid:GetAttribute("Downed") == true then
			local ColourTween = TweenModule:To(bar, {
				BackgroundColor3 = Color3.fromRGB(255, 220, 137)
			}, 0.25, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.InOut)
			ColourTween:Play()
		else
			local ColourTween = TweenModule:To(bar, {
				BackgroundColor3 = OriginalColour
			}, 0.25, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.InOut)
			ColourTween:Play()
		end
	end)

	self._Trove:Connect(Humanoid.Died, function()
		local ratio = 0.01
		local TargetTransparency = 1

		local tween = TweenModule:To(bar, {
			Size = UDim2.new(ratio, 0, 1, 0)
		}, 0.25, TweenModule.EasingStyle.Quart, TweenModule.EasingDirection.Out)


		local Tween2 = TweenModule:CircTo(UIElements.PlayerStats.Health.Frame, {
			GroupTransparency = TargetTransparency
		}, 1.5, TweenModule.EasingDirection.InOut)
		Tween2:Play()
		tween:Play()
	end)
end

function Framework:SetupLevelXPBar(bar)
	if not bar then return end

	bar.Size = UDim2.new(0.01, 0, 0.01, 0) -- Start full

	local function update()

		local ratio = PlayerData:FindFirstChild("LevelXP").Value / PlayerData:FindFirstChild("MaxLevelXP").Value
		local tween = TweenModule:To(bar, {
			Size = UDim2.new(ratio, 0, 1, 0)
		}, 0.25, TweenModule.EasingStyle.Sine, TweenModule.EasingDirection.InOut)

		tween:Play()
	end

	self._Trove:Connect(PlayerData:FindFirstChild("LevelXP").Changed, function()
		update()
	end)

	self._Trove:Connect(PlayerData:FindFirstChild("MaxLevelXP").Changed, function()
		update()
	end)

	update()

end

function Framework:SetupStaminaBar(bar)
	if not bar then return end

	local function updateStamina()
		local DownedAttribute = Humanoid:GetAttribute("Downed")

		local maxStamina = Humanoid:GetAttribute("MaxStamina") or 100
		local stamina = Humanoid:GetAttribute("Stamina") or maxStamina
		local ratio = stamina / maxStamina

		if DownedAttribute == false then

			local TargetTransparency = 0

			local tween = TweenModule:To(bar, {
				Size = UDim2.new(ratio, 0, 1, 0)
			}, 0.25, TweenModule.EasingStyle.Quart, TweenModule.EasingDirection.Out)

			local Tween2 = TweenModule:CircTo(UIElements.PlayerStats.Stamina.Frame, {
				GroupTransparency = TargetTransparency
			}, 0.5, TweenModule.EasingDirection.InOut, function()
				UIElements.PlayerStats.Stamina.Frame.Visible = true
			end)

			tween:Play()
			Tween2:Play()
		else
			local ratio = 0.01
			local TargetTransparency = 1

			local tween = TweenModule:To(bar, {
				Size = UDim2.new(ratio, 0, 1, 0)
			}, 0.25, TweenModule.EasingStyle.Quart, TweenModule.EasingDirection.Out)


			local Tween2 = TweenModule:CircTo(UIElements.PlayerStats.Stamina.Frame, {
				GroupTransparency = TargetTransparency
			}, 0.5, TweenModule.EasingDirection.InOut, function()
				UIElements.PlayerStats.Stamina.Frame.Visible = false
			end)
			Tween2:Play()
			tween:Play()
		end
	end

	-- Initial update
	updateStamina()

	-- Listen for changes
	self._Trove:Connect(Humanoid.AttributeChanged, function(attribute)
		if attribute == "Stamina" or attribute == "MaxStamina" or attribute == "Downed" then
			updateStamina()
		end
	end)
end

function Framework:RefreshUI()
	self:InitializeStatusBars()
	---self:RefreshInventory()
end

function Framework:TweenUI(object, properties, duration, easingStyle, easingDirection)
	local tweenInfo = TweenInfo.new(
		duration or 0.5,
		Enum.EasingStyle[easingStyle or "Quad"],
		Enum.EasingDirection[easingDirection or "Out"]
	)

	local tween = TweenService:Create(object, tweenInfo, properties)
	--tween:Play()
	return tween
end

function Framework:ToggleRobloxInventory(enabled)
	self.Status.RobloxInventoryEnabled = enabled
	StarterGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, enabled)
end

function Framework:ToggleFrameworkInventory(enabled)
	if UIElements.Hotbar and self.UIElements.Hotbar.Frame then
		UIElements.Hotbar.Frame.Visible = enabled
	end
end

function Framework:IsInMenu()
	return self.Status.InMenu
end

function Framework:Cleanup()
	self._Trove:Clean()
end

return Framework.new()

I tried Adding in my own OnCharacterAdded but it does not work.

Here is a video:

Turn off ResetOnSpawn in your ScreenGui

2 Likes

Thanks. Yeah I realised it was not disabled. Thank you

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.