Button script not working for one button after player is morphed

  1. What do you want to achieve?

I have a module script in starterPlayerScripts that manages all the buttons in my game’s GUI. I load this module script using a module loader. This script works perfectly fine for every button, up until I morph the player’s character. I want to fix a bug happening where one specific button stops working for some reason.

  1. What is the issue?

Once I morph the player’s character, the button inside a game GUI I bring up doesn’t work. There’s no errors or anything, it just doesn’t work. The button was made the same way as all the other buttons and coded into the script the same as the other buttons.

In the video I demonstrate how all the gui buttons work when pressed (shown by their intended script running and the warn/print statements in the console.) I also show that the button in question (the “menu” button under GameGui) works by manually enabling it and clicking it. Once I spawn though and the button appears when it actually should, when I click it, nothing happens. When I manually enable any other menu and click it after spawning it still functions as normal, so why does this one button fail?

The button handler modulescript in starterPlayerScripts:

local ButtonHandler = {}
local buttons = {}
local connections = {}

local gameGui = plr.PlayerGui:WaitForChild("GameGui")
table.insert(buttons,gameGui.menu.menu)

-- Functions --
local function checkDebounce(button)
	-- Check Player's Debounce --
	if button:GetAttribute("debounce") == false then
		task.wait(0.001)
		button:SetAttribute("debounce",true)
		return true
	else
		return false
	end
end

local function buttonClicked(button)
	-- Switch Case Depending On Button Pressed To Call Functions --
	local buttons = {
		["menu"] = function()
			print("THIS WORKS")
		end,
	}

	if buttons[button.Name] then
		buttons[button.Name]()
	else 
		buttons["default"]()
	end

end

function ButtonHandler:Init()
	-- Manage Most Menu Buttons --
	for _, button in buttons do
		button.MouseButton1Click:Connect(function() 

			if not checkDebounce(button) then return end
			soundModule:playSound("Button")
			warn(script.Name.. ": " ..button.Name.. " Pressed By " ..plr.Name)
			buttonClicked(button)
			print(script.Name.. ": " ..plr.Name.. " " ..button.Name.. " Button Ran")
			button:SetAttribute("debounce",false)

		end)
	end

	-- Manage View / Spawn Buttons --
	pageLayout.CurrentPage.Changed:Connect(function()
		for _, connection in connections do
			connection:Disconnect()
		end

		for _,item in pageLayout.CurrentPage:GetDescendants() do
			-- Type Checks --
			if item.ClassName ~= "TextButton" then continue end
			if item:GetAttribute("Type") == nil then continue end

			local connection = item.MouseButton1Click:Connect(function()
				-- When View Button Pressed --
				if item:GetAttribute("Type") == "View" then
					warn(script.Name.. ": " ..item.Name.. " View Button Pressed By " ..plr.Name)
					previewModule:viewOperator(item)

					-- When Spawn Button Pressed --
				elseif item:GetAttribute("Type") == "Spawn" then
					warn(script.Name.. ": " ..item.Name.. " Spawn Button Pressed By " ..plr.Name)
					guiModule:transitionIn(1)
					replicatedStorage.Remotes.Spawn:FireServer(item.Name,customizationModule.skinTone)

				else
					warn(script.Name.. ": Button type not found!?")
				end
			end)
			table.insert(connections, connection)
		end
	end)
	end
end

return ButtonHandler

Since this issue only happens after the player spawns, I feel it would be relevant to include the spawning scripts, so here they are:
SpawnService, a modulescript inside serverScriptService called when the spawn button is pressed for any operator -

local SpawnService = {}

-- Script Variables --
local replicatedStorage = game:GetService("ReplicatedStorage")
local customizationModule = require(replicatedStorage.Modules.CustomizationModule)

function SpawnService:Init()
	-- Spawn Player / Set Operator --
	replicatedStorage.Remotes.Spawn.OnServerEvent:Connect(function(plr,operatorName,skinTone)
		-- Function Variables --
		local operator = plr.PlayerGui.OperatorModels:FindFirstChild(operatorName,true):Clone()
		local character = plr.Character
		local animate = plr.Character.Animate
		animate.Parent = game.ReplicatedStorage

		-- Destroy Unneccessary Parts of Model --
		if operator.Torso:FindFirstChild("Gun") ~= nil then
			operator.Torso:FindFirstChild("Gun"):Destroy()
		end
		operator:FindFirstChildWhichIsA("Animation"):Destroy()
		
		-- Clone Important Scripts Into Model --
		character.Health:Clone().Parent = operator
		
		-- Set Operator Properties --
		operator.Parent = workspace
		customizationModule:setSkinTone(operator,skinTone)
		operator.HumanoidRootPart.Anchored = false
		operator.Name = " "
		plr.Character = operator

		animate.Parent = plr.Character

		-- Fire Client For Client-Side Preparation --
		replicatedStorage.Remotes.Spawn:FireClient(plr,operatorName)

		-- Spawn Player --
		local spawnPoints = workspace.SpawnPoints:GetChildren()
		local target = spawnPoints[math.random(#spawnPoints)]
		plr.Character.HumanoidRootPart.CFrame = target.CFrame
	end)
end

return SpawnService

SpawnHandler, a modulescript in starterPlayerScripts called when the server does its thing above -

local SpawnHandler = {}

-- Script Variables --
local plr = game:GetService("Players").LocalPlayer
local replicatedStorage = game:GetService("ReplicatedStorage")
local modules = replicatedStorage.Modules
local camModule = require(modules.CameraModule)
local guiModule = require(modules.GuiModule)
local soundModule = require(modules.SoundModule)
local customizationModule = require(modules.CustomizationModule)
local previousOperatorName = nil

function SpawnHandler:Init()
	-- Set Player's Camera, Gui, and Music --
	replicatedStorage.Remotes.Spawn.OnClientEvent:Connect(function(operatorName)
		previousOperatorName = operatorName
		camModule:setCam(Enum.CameraType.Custom, plr.Character.Humanoid)
		workspace.CurrentCamera.CameraSubject = plr.Character:WaitForChild("Humanoid")
		guiModule:setGui("GameGui","TouchGui")
		guiModule:setCoreGui("ResetButtonCallback",true)
		soundModule:fadeSound("MenuMusic",1)
		guiModule:transitionOut(1)
	end)

return SpawnHandler

Let it be known that I have removed a lot of code I believed was unnecessary. In the actual code there are no errors, so any you spot here are purely my mistake in editing this to be less lengthy. I think you can get the idea of what’s happening though. If you have any questions about anything you see in the console of the video or in this code let me know, I’ll be happy to answer them.

  1. What solutions have you tried so far?

I’ve tried commenting out certain parts of different module scripts related to spawning and the gui to no effect.

I’ve also tried adding waits to the client-side spawning script and seeing exactly when it stopped working, and somehow still couldn’t figure out exactly when or why it stopped working.

Looking through the “similar posts” thing I did not see any that looked relevant.

P.S Thank you for reading this pretty long post. Any help is appreciated! I’m known to overlook some very basic things sometimes, so if it turns out to be some small bug, sorry for wasting your time… ._.

EDIT: I accidentally uploaded the wrong video of a previous bug that has already been resolved - sorry! It’s been fixed now.
EDIT 2: Removed a test module require() that was unused in the code to avoid confusion.

1 Like

Hello, it’s been almost 24 hours, so I figured I’d post an update for people to see this is still a thing - I still have not figured this out. I have no new information unfortunately, but this is pretty important to the intended function of the game. Thanks!

Day 2: The issue is still unresolved. I tried using Roblox AI (which imo is not great- but I don’t have ChatGPT and stuff right now) and it did not help much. It said, “the issue is that the GameGui button is not properly re-initialized when the player’s GUI is recreated after spawning.” The only issue I have with this is every other button works and the provided script it gave me did not work.

In the video you posted, the ScreenGui containing the button in question has ResetOnSpawn set to true. When the ButtonHandler module is first executed, it will find the original button and initialize all the connections with that specific button, which is why it works fine when you manually enable then interface and click on it prior to spawning in.

Once you spawn in, that original ScreenGui will be destroyed and replaced by a fresh copy. The “buttons” table at the top of ButtonHandler only contains a reference to the original button, so even if you were to run ButtonHandler:Init() again, for instance, it would just reconnect to the now-destroyed original button.

1 Like

Just checked the screenGui vs. the others for this and realized I forgot to set the ResetOnSpawn… This is exactly what I mean by “I’m known to overlook some very basic things” xD

Changing the setting worked, thanks a ton!

1 Like

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