My script works in one game, but not another [SOLVED]

I’m currently doing work for a large group and I created something that works in my testing game, works in studio, works with all my tests. But when it gets put into their game it doesn’t work.

Here’s the script:

script.Parent.Touched:Connect(function(hit)
	local player = hit.Parent
	local plr = game.Players:FindFirstChild(player.Name)
	local JacksonsShop = game.ServerStorage:WaitForChild("GUIs",100):FindFirstChild("JacksonsShop"):Clone()
	JacksonsShop.Parent = plr:WaitForChild("PlayerGui",100)
end)

script.Parent.TouchEnded:Connect(function(hit)
	local plr = game.Players:FindFirstChild(hit.Parent.Name)
	plr.PlayerGui:WaitForChild("JacksonsShop",100):Destroy()
end)

It works 100% of the time in my test game, however when put in the actual game I get these errors:


At first I thought it had to do with the script running before the game loaded so I destroyed the script by waiting for nearly everything. At this point though, I just don’t know.

Please drop help below.

edit: the problem was that for some reason the script could not access ServerStorage.GUIs even though it itself was a server script. I moved the GUI into ReplicatedStorage and the issue fixed itself.

1 Like

This error happens because plr is nill, you should use game.Players:GetPlayerFromCharacter().

The script:

script.Parent.Touched:Connect(function(hit)
	local player = hit.Parent
	local plr = game.Players:GetPlayerFromCharacter(player)
    if plr then
	local JacksonsShop = game.ServerStorage:WaitForChild("GUIs",100):FindFirstChild("JacksonsShop"):Clone()
	JacksonsShop.Parent = plr:WaitForChild("PlayerGui",100)
   end
end)

script.Parent.TouchEnded:Connect(function(hit)
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
    if plr then
	plr.PlayerGui:WaitForChild("JacksonsShop",100):Destroy()
  end
end)

I took your advice and all of the other errors have subsided.
Now the only issue is this:
image
here is the re written script:

> local GUIs = game.ServerStorage:WaitForChild("GUIs")
> 
> function TouchStart(hitPart)
> 	local character = hitPart.Parent
> 	if character:IsA('Model') then
> 	local player = game.Players:GetPlayerFromCharacter(character)
> 	local gui = GUIs:FindFirstChild("JacksonsShop"):Clone()
> 	gui.Parent = player:WaitForChild("PlayerGui")
> 	end
> end
> 
> function TouchEnd(hitPart)
> 	if hitPart.Parent:IsA('Model') then
> 	local player = game.Players:GetPlayerFromCharacter(hitPart.Parent)
> 	local playerGui = player:WaitForChild("PlayerGui")
> 	if playerGui:FindFirstChild("JacksonsShop") ~= nil then
> 		local gui = playerGui:FindFirstChild("JacksonsShop")
> 		gui:Destroy()
> 		end
> 	end
> end
> 
> script.Parent.Touched:Connect(TouchStart)
> script.Parent.TouchEnded:Connect(TouchEnd)

edit: oh yeah I understand that it’s only a warning, but it’s just simply not working

It is a simple warning, it says it will yield until it finds GUIs in ServerStorage (I think you don’t put anything named GUIs in ServerStorage)

edit: Can you show a photo with all the things from ServerStorage?

That’s what I thought too.
image
But it exists.

If the script is on Server, it should not do this, but if the script is the script named Handler it can’t view ServerStorage (Only scripts can)

It’s saying that player is nil.
Your brick is touching a wall or something else but a players character.

You should do:

local plr = game.Players:FindFirstChild(hit.Parent.Name)
if plr == nil then return end

The Handler is a server script.
image

Can you test on the server if you will see the GUIs in ServerStorage?

1 Like

I’m all out of ideas. I’m going to put the gui inside the script and see if that works.

I have no idea what’s going on at this point:
image
in theory my script should work

It seems like GUIs is being set to nil. I know you already fixed this issue above, but I have a theory (it’s probably wrong, but I’m guessing you are willing to try anything at this point).

First, try putting your script in ServerScriptService. Not that it makes a difference (in theory), but theory right now is playing against us.

Next I suggest you use GetService("ServerStorage") instead of using the . . Same thing for game:GetService(“Players”) but that doesn’t seem to cause issues. Regardless, at least try it for ServerStorage.

I am just playing on a (bad) hunch that you are getting a funny interaction with ServerStorage. As for your recent change (putting the GUIs folder in the script) I don’t know what code you changed after you put it in there. That would be helpful to understand the new problems you are having :wink:

2 Likes

For this I would recommend putting it in ReplicatedStorage.

Please note this is a quick type up.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GUIs = ReplicatedStorage:WaitForChild("GUIs")

script.Parent.Touched:Connect(function(Obj)
local Player = Players:GetPlayerFromCharacter(Obj.Parent)
if Player ~= nil then else return end
if Player:WaitForChild("PlayerGui"):FindFirstChild("JacksonsShop") == nil then
    local ShopGui = GUIs["JacksonsShop"]:Clone()
    ShopGui.Parent = Player:WaitForChild("PlayerGui")
end
end)

script.Parent.TouchEnded:Connect(function(Obj)
    local Player = Players:GetPlayerFromCharacter(Obj.Parent)
    if Player ~= nil then else return end
    if Player.PlayerGui:FindFirstChild("JacksonsShop") ~= nil then
        Player.PlayerGui["JacksonsShop"]:Destroy()
    end
end)

The part you said don’t make much changes in speed or anything else, but it waits so the service is loaded. If he puts the GUI in the script, with this script he can solve this problem:

function TouchStart(hitPart)
	local character = hitPart.Parent
   if character:IsA('Model') then
 	local player = game.Players:GetPlayerFromCharacter(character)
 	local gui = script.GUIs:FindFirstChild("JacksonsShop"):Clone()
	gui.Parent = player:WaitForChild("PlayerGui")
 	end
 end
 
 function TouchEnd(hitPart)
 	if hitPart.Parent:IsA('Model') then
 	local player = game.Players:GetPlayerFromCharacter(hitPart.Parent)
 	local playerGui = player:WaitForChild("PlayerGui")
 	if playerGui:FindFirstChild("JacksonsShop") ~= nil then
 		local gui = playerGui:FindFirstChild("JacksonsShop")
 		gui:Destroy()
 		end
 	end
 end
 
 script.Parent.Touched:Connect(TouchStart)
 script.Parent.TouchEnded:Connect(TouchEnd)
1 Like

Why you said

if Player ~= nil then else return end

instead of

if not Player then return end

this is much simpler and why you put a random else?
If he puts the GUIs in the script, and the script in ServerScriptService then the client can’t get it. If you put it in the workspace or ReplicatedStorage any exploiter may access the shop from anywhere. So, putting the GUIs in the script and the script in ServerScriptService is the most secure way.

He’s not storing it in ServerScriptService tho.

Honestly I’d just write it like this:

local SHOP = game.ServerStorage:WaitForChild("GUIs"):WaitForChild("JacksonsShop")

local chars = {}
script.Parent.Touched:Connect(function(hit)
	local player = game.Players:FindFirstChild(hit.Parent.Name)
	if not player or chars[hit.Parent] then return end --If player doesn't exist OR if the player already has the shop gui
	
	local JacksonsShop = SHOP:Clone()
	chars[hit.Parent] = JacksonsShop
	JacksonsShop.Parent = player.PlayerGui
end)

script.Parent.TouchEnded:Connect(function(hit)
	local JacksonsShop = chars[hit.Parent]
	if JacksonsShop then
		JacksonsShop:Destroy()
		chars[hit.Parent] = nil
	end
end)

But touchEnded events like these are really scetchy tho, sometimes it doesnt call TouchEnded at all.
This should work tho.

Agreed.

In this case I’d use magnitude to remove the Shop when the Player is at a distance as opposed to TouchEnded.

I don’t say he is storing it in ServerScriptService, i said if he is storing in ServerScriptService.

Not reverses the logical state of an operand, ~= checks for negation of equality. Simplicity is a subjective thing and can differ between people, so it’s fine to use either one. The hanging else is the only bit that’s bad to include; blank cases in an if statement aren’t really savory.

2 Likes