Parts of a model script

I have a script where if you click any part of the model, a GUI would appear asking to buy it, it, when yes is clicked the image they want to upload goes on the surface of the part, (already scripted), I am just having an issue for when they click on any part the GUI does not appear. (It also needs for when someone clicks on it that part would be theirs, not any other parts).
Script in ScreenGUI:

local decalparts = workspace.DecalParts:FindFirstChild('DecalPart',true)
local part = decalparts.ClickDetector
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Fram = script.Parent.Decal
part.MouseClick:Connect(function()
guiFrame.Visible = true
    if Owns.Value == true then
        Fram.Visible = true
        guiFrame.Visible = false
    end
if points ~= nil then
	points.Value = points.Value - 10
	    Owns.Value = true
	   script.Parent.Parent.Visible = false
	   decalparts.SurfaceGui.TextLabel.Text = player.Name.. "'s Decal"
end
end)

Workspace:
Part

2 Likes

You’d have to make a loop to go through these parts, this is what I would do
I’ve also commented on what I think could be the issue with the gui not showing

local decalparts = workspace.DecalParts
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Frame = script.Parent.Decal

for _, part in next, decalparts:GetChildren() do
	part.ClickDetector.MouseClick:Connect(function()
		guiFrame.Visible = true
		
		if Owns.Value then -- I'm guessing there may be in issue with this, make sure that Owns is true
			Frame.Visible = true
			guiFrame.Visible = false
		end
		
		if points then
			points.Value = points.Value - 10
			Owns.Value = true
			script.Parent.Parent.Visible = false
			decalparts.SurfaceGui.TextLabel.Text = player.Name.. "'s Decal"
		end
	end)
end
2 Likes

Works perfectly except for

decalparts.SurfaceGui.TextLabel.Text = player.Name.. "'s Decal"

Do you know why? Edit: How do I also make it so they need to have the required points? Since I can just buy this with 0.

2 Likes

To check they have enough points you’d do if points and points.Value >= 10 then

What error are you getting on the SurfaceGui part?

1 Like

Their name does not seem to print.

1 Like

Oh yeah, probably is because you did the concatenate .. right after the players name

Do this instead:
namedecalparts.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"

1 Like

You need to specify what’s wrong. If you only say “it doesn’t work!” we’ll never be able to help you properly.

Assuming from your code and image, decalparts is a Model. In this case, you’re forgetting to reference the part that has the SurfaceGui. Indexing it after decalparts should fix the problem. If DecalParts doesn’t have such a part, then you’re referencing the wrong model. Where is your SurfaceGui in your explorer?

That doesn’t do any difference.

1 Like

Here is the updated script is it good?

local decalparts = workspace.DecalParts
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Frame = script.Parent.Decal

for _, part in next, decalparts:GetChildren() do
	part.ClickDetector.MouseClick:Connect(function()
		guiFrame.Visible = true
		
		if Owns.Value then 
		Frame.Visible = true
			guiFrame.Visible = false
		end
		
		if points and points.Value >= 10
		then
			points.Value = points.Value - 10
			Owns.Value = true
			script.Parent.Parent.Visible = false
			decalparts.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"
		end
	end)
end
1 Like

Thanks.
Surfa

1 Like

In this case, all you have to do is apply it in a loop.

Taking @Wonuf’s already updated code:

local decalparts = workspace.DecalParts
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Frame = script.Parent.Decal

for _, part in next, decalparts:GetChildren() do
   part.ClickDetector.MouseClick:Connect(function()
   	guiFrame.Visible = true
   	
   	if Owns.Value then 
   	Frame.Visible = true
   		guiFrame.Visible = false
   	end
   	
   	if points and points.Value >= 10
   	then
   		points.Value = points.Value - 10
   		Owns.Value = true
   		script.Parent.Parent.Visible = false
   		part.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"
   	end
   end)
end

Edit: I’d recommend you to read on for loops and generally how looping works in Lua. Once you’re familiar with that, you should read up on how GetChildren() works, and why it is useful.

4 Likes

After running a couple of tests the statement

part.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"

does not print the user for example: reteyetet’s Decal… Do you have anymore suggestions?

1 Like

After analyzing your situation, I remembered that I’ve worked on such thing a month ago. A method I used to detect whenever a model part is being clicked is to add a click detector in every model part and then constantly loop through its children to detect any clicks. An example would be :

local model = game.workspace.model -- declaring the model

while true do 
    -- constantly looping 
    for _,part in pairs(model:GetChildren()) do
        -- detecting any input 
part.ClickDetector.MouseClick:Connect(yourfunction)
end
end

This example may solve your situation.
Edit : I also recommend adding some if statements to check if the child is a part and meets all your criterias in order to run it.

1 Like

Does the rest of the code before that work though?

And what do you mean by “print” exactly? Do you mean the text showing on the Gui, or on the output?

Any errors?

Any case I can think of this not working but the rest working is if the part does not have a SurfaceGui child. Do the points deduct?

-What I define “print” as was the Text on the TextLabel (Sorry if that was not clear)
-I do not have any errors at all.
-The rest of the code works.

This is a LocalScript, correct?

Yes it is a LocalScript. I even added on to upload the image, here is a updated script of it so far.

local decalparts = workspace.DecalParts
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Frame = script.Parent.Decal
local yes = script.Parent.Frame.Yes

for _, part in next, decalparts:GetChildren() do
   part.ClickDetector.MouseClick:Connect(function()
   	guiFrame.Visible = true
   	
   	if Owns.Value then 
   	Frame.Visible = true
   		guiFrame.Visible = false
   	end
local decal = part:FindFirstChild("DecalPart").decal
local event = game:GetService("ReplicatedStorage"):WaitForChild("imagedec")
local text = script.Parent.Decal.imageid
script.Parent.Decal.imageupload.MouseButton1Down:Connect(function()

		local textid = text.Text
	
	event:FireServer(textid)
end)
end)
   	
yes.MouseButton1Down:Connect(function()
   	if points and points.Value >= 10
   	then
   		points.Value = points.Value - 10
   		Owns.Value = true
   		script.Parent.Frame.Visible = false
   		part.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"
   	end
end)
end

I got the main idea, but I do not quite understand whats your main point?

My main point is, That is how I would handle your situation, By creating a handler
I’m giving you an alternative solution to your problem which could help in the long run to avoid lag if you’re going to have more assets and scripts in your game.

(Sorry if it is at all complicated, Just providing alternative solutions)

1 Like

On second thought, if you only need a script for that one model go with the methods the others are mentioning, If you need a script for multiple models then in my opinion, the method i proposed would be more appropriate.

That would not avoid lag, that would just add additional performance cost.

Your response is not related to the problem, and I wouldn’t recommend implementing it.

ClickDetectors are a thing for a reason; they should be used for their own purpose.

This line would break your code. When looping, you’re already obtaining every single DecalPart inside the DecalParts model.

Also you’ve got ends missplaced.

Here:

local decalparts = workspace.DecalParts
local player = game.Players.LocalPlayer
local EP = player:FindFirstChild("leaderstats1")
local points = EP:FindFirstChild("ElitePoints")
local Owns = script.Parent.Frame.Owns
local guiFrame = script.Parent.Frame
local Frame = script.Parent.Decal
local yes = script.Parent.Frame.Yes

for _, part in next, decalparts:GetChildren() do
   part.ClickDetector.MouseClick:Connect(function()
   	guiFrame.Visible = true
   	
   	if Owns.Value then 
   	Frame.Visible = true
   		guiFrame.Visible = false
   	end
local decal = part.Decal
local event = game:GetService("ReplicatedStorage"):WaitForChild("imagedec")
local text = script.Parent.Decal.imageid
script.Parent.Decal.imageupload.MouseButton1Down:Connect(function()

		local textid = text.Text
	
	event:FireServer(textid)
end)
end)
end
   	
yes.MouseButton1Down:Connect(function()
   	if points and points.Value >= 10
   	then
   		points.Value = points.Value - 10
   		Owns.Value = true
   		script.Parent.Frame.Visible = false
   		part.SurfaceGui.TextLabel.Text = player.Name .. "'s Decal"
   	end
end)