BoolValue related issue with changes not being tracked correctly (Customization UI)

  1. What do you want to achieve? Make my ServerScript track boolean values changes and act accordingly

  2. What is the issue? The BoolValue is being ignored by the script

  3. What solutions have you tried so far? I’ve searched for some solutions such as trying to use GetPropertyChangedSignal( "Value" ) but that didn’t work either

Hi! I am currently working on a customization UI for my game. It is going well except for the part of removing the player’s tools (Which are weapons with scripted camera stuff) to prevent camera glitches, thus, I’ve tried implementing a solution by temporary cleaning the player’s backpack upon entering the customization UI, to later retrieve all the tools back when the player leaves the customization UI. In order to track whenever the player enters/leaves the customization UI, I am using a BoolValue inside ReplicatedStorage (Which I believe is fine located but correct me if not) controlled by a well working LocalScript that takes care of the whole UI. The real issue comes when trying to remove the player’s weapons as the BoolValue doesn’t seem to get tracked correctly by the script, even while using print() to track where the issue is I only get the message of the BoolValue being found and that’s about it. Ahead I will share a shorter version of the ServerScript, responsible for providing players with their weapons upon respawn based on their team and purchased gamepasses, as expected we want the player to receive back these weapons once leaving the customization UI which is why I decided to modify this script to implement this needed feature for the customization UI to work properly.

local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local ServerStorage = game:GetService("ServerStorage")
local StarterPack = game:GetService("StarterPack")
local MarketplaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local teamWeapons = ServerStorage:WaitForChild("TeamWeapons")
local customizationValue = ReplicatedStorage:WaitForChild("InCustomization")

local Team1Weapons = {
	"Example1",
	"Example2",
	"Example3"
}

local Team2Weapons = {
	"Weapon1",
	"Weapon2",
	"Weapon3"
}

local gamepassWeapons = {
	{Id = 12345678, Name = "NicerWeapon"},
	{Id = 87654321, Name = "GreaterWeapon"},

}

-- Function to clear the player's loadout
local function clearLoadout(player)
	local backpack = player:FindFirstChild("Backpack")
	local character = player.Character

	if character then
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:UnequipTools()
		end
	end

	if backpack then
		for _, tool in ipairs(backpack:GetChildren()) do
			if table.find(Team1Weapons, tool.Name) or table.find(Team2Weapons, tool.Name) then
				tool:Destroy()
			end
		end
	end

	for _, tool in ipairs(StarterPack:GetChildren()) do
		if tool:IsA("Tool") and (table.find(Team1Weapons, tool.Name) or table.find(Team2Weapons, tool.Name)) then
			tool:Destroy()
		end
	end
end


-- Function to give the player's team loadout
local function giveLoadout(player, teamName)
	local weaponsFolder = teamWeapons:FindFirstChild(teamName)
	if weaponsFolder then
		local weaponNames = teamName == "Team1" and Team1Weapons or Team2Weapons
		for _, weaponName in ipairs(weaponNames) do
			local weapon = weaponsFolder:FindFirstChild(weaponName)
			if weapon then
				local starterWeapon = weapon:Clone()
				starterWeapon.Parent = StarterPack

				local clonedWeapon = weapon:Clone()
				clonedWeapon.Parent = player.Backpack
			end
		end
	end
end

-- Function to give gamepass weapons
local function giveGamepassWeapons(player)
	local backpack = player:FindFirstChild("Backpack")
	if backpack then
		for _, gamepassWeapon in ipairs(gamepassWeapons) do
			if MarketplaceService:UserOwnsGamePassAsync(player.UserId, gamepassWeapon.Id) then
				if not backpack:FindFirstChild(gamepassWeapon.Name) then
					local weapon = ServerStorage:FindFirstChild(gamepassWeapon.Name)
					if weapon then
						local clonedWeapon = weapon:Clone()
						clonedWeapon.Parent = backpack
					end
				end
			end
		end
	end
end

-- Function to handle entering and exiting customization UI
local function handleCustomizationState(player)
	local customizationValue = ReplicatedStorage:WaitForChild("InCustomization")
	print("InCustomization BoolValue found in ReplicatedStorage.")
	
	-- Use 'Changed' to detect when InCustomization changes
	customizationValue.Changed:Connect(function(newState)
		if newState == true then
			print("Customization mode started, removing weapons...")
			clearLoadout(player)
		elseif newState == false then
			print("Exiting customization mode, restoring weapons...")
			local team = player.Team
			if team then
				giveLoadout(player, team.Name)
				giveGamepassWeapons(player)
			end
		end
	end)
end

-- Function to handle player loadout upon joining and respawn
local function onPlayerAdded(player)
	player.CharacterAdded:Connect(function()
		local team = player.Team
		if team then
			clearLoadout(player)
			giveLoadout(player, team.Name)
			giveGamepassWeapons(player)
		end
	end)

	-- Start handling customization state for the player
	handleCustomizationState(player)
end



-- Connect team change event to update loadout accordingly
local function onTeamChanged(player)
	player:GetPropertyChangedSignal("Team"):Connect(function()
		local team = player.Team
		if team then
			clearLoadout(player)
			giveLoadout(player, team.Name)
			giveGamepassWeapons(player)
		end
	end)
end

Players.PlayerAdded:Connect(function(player)
	onPlayerAdded(player)
	onTeamChanged(player)
end)

for _, player in ipairs(Players:GetPlayers()) do
	onPlayerAdded(player)
	onTeamChanged(player)
end

I know the Script is still very long, I tried my best making it shorter but still complete enough to avoid missing anything. As you can see in handleCustomizationState function, when using ‘Changed’ to track changes on the BoolValue, it’s not triggering despite having actual changes in the true and false values each time the player enters and leaves the customization UI. Maybe I’ve used GetPropertyChangedSignal( "Value" ) wrong all along but after several tests it just has the same useless impact. Any kind of help is heavily appreciated as I am stuck right now in this situation. Don’t hesitate on asking for any other possible required detail in order to find a solution. :smiley:

I’m actually getting your print()s just fine. Are you sure the value is actually being changed in the first place?

Also, you’ll need to place the InCustomization instance in each player instance if you wish to have each player go into the menu on their own rather than all together.

Thanks for replying. Yes, the value is indeed getting changed, I’ve verified this multiple times.

So if I understand correctly, you are saying that instead of placing InCustomization inside ReplicatedStorage I should just place it inside Players? I have to admit I am not that skilled into Lua, I just know the basics so I can sometimes miss a few simple things like these, I will try this and let you know the results, since now that you mention it, it does make sense, I haven’t thought of that little detail…

object.changed:Connect(function(property)

I may be wrong but I believe when this event is fired it returns the Property, not the value of the property, in your case it would be returning Value assuming the value is actually changing.

Thank you guys for replying.

I have come up with the solution by using a RemoteEvent triggered after entering the customization UI, this led to setting the BoolValue to true and false each time, thus making the customizationValue.Changed:Connect(**function**(newState) trigger and making the weapons get removed from the player’s inventory. I also had to create the InCustomization and add it as a children of the player (Thanks IxGamerXL for pointing this out :smiley:)

Once again, thank you a lot for the help! :muscle:t4: