The error shows up at line 11 (The clicked function) It works in studio but not ingame. I tried waiting for the mouse but it just waits infinitely. The error that shows up (without the waiting) is "attempt to index local 'mouse' (a nil value)". I've checked and everything seems to be fine. when I changed mouse = player:GetMouse() to mouse = player (thinking maybe player was already the mouse), it said: Hit is not a part of Player.
part = script.Parent.PrimaryPart mouseClicked = false partMoving = false collision = false isincollision = false originalcolor = {} outOfBounds = false function clicked(player) mouse = player:GetMouse() playerSlot = PlayerSlot(player) for i,v in pairs(script.Parent:GetChildren()) do local increment = 0 if v.ClassName == "Part" then increment = increment+1 table.insert(originalcolor, v.BrickColor) end end if mouseClicked == false then mouseClicked = true if partMoving == false then partMoving = true wait() mouseClicked = false MovePart(player) else wait() mouseClicked = false PlacePart(player) end end end function RoundUp(number) local roundNumber = number-(number%0.5) return roundNumber end function MovePart(player) local mouse = player:GetMouse() while partMoving == true do script.Parent:SetPrimaryPartCFrame(CFrame.new((RoundUp(mouse.Hit.p.x)), script.Parent.PrimaryPart.CFrame.Y, (RoundUp(mouse.Hit.p.Z)))) wait() end end function PlacePart(player) local mouse = player:GetMouse() if isincollision == false then if outOfBounds == false then partMoving = false end end end script.Parent.PrimaryPart.Changed:connect(function() for i,modelpart in pairs(script.Parent:GetChildren()) do if modelpart.ClassName == "Part" then for i,part in pairs(modelpart:GetTouchingParts()) do if part.Parent ~= script.Parent then if collision == false then collision = true end end end end end if collision ~= false then isincollision = true for i,v in pairs(script.Parent:GetChildren()) do if v.ClassName == "Part" then if v.BrickColor ~= BrickColor.new("Really red") then v.BrickColor = BrickColor.new("Really red") v.Transparency = 0.5 end end end else isincollision = false local increment = 0 if outOfBounds == false then for i,v in pairs(script.Parent:GetChildren()) do if v.ClassName == "Part" then increment = increment+1 local color = tostring(originalcolor[increment]) if v.BrickColor == BrickColor.new("Really red") then v.BrickColor = BrickColor.new(color) v.Transparency = 0 end end end end end collision = false end) function PlayerSlot(player) for i,v in pairs(game.Workspace.Slots:GetChildren()) do if v.Slot_Owner.Value == player.Name then print(v) return v end end end script.Parent.PrimaryPart.Changed:connect(function() local partSize = script.Parent.PrimaryPart.Size local partPos = script.Parent.PrimaryPart.CFrame local slotPosX = playerSlot.slot.Position.X local slotPosZ = playerSlot.slot.Position.Z local slotSizeX = playerSlot.slot.Size.X local slotSizeZ = playerSlot.slot.Size.Z local oneOutOfBounds = false if oneOutOfBounds == false then if partPos.X + partSize.X/2 > slotPosX+slotSizeX/2 then oneOutOfBounds = true elseif partPos.X - partSize.X/2 < slotPosX-slotSizeX/2 then oneOutOfBounds = true end end if oneOutOfBounds == false then if partPos.Z + partSize.Z/2 > slotPosZ+slotSizeZ/2 then oneOutOfBounds = true elseif partPos.Z - partSize.Z/2 < slotPosZ-slotSizeZ/2 then oneOutOfBounds = true end end if oneOutOfBounds == true then outOfBounds = true for i,v in pairs(script.Parent:GetChildren()) do if v.ClassName == "Part" then if v.BrickColor ~= BrickColor.new("Really red") then v.BrickColor = BrickColor.new("Really red") v.Transparency = 0.5 end end end else outOfBounds = false end end) script.Parent.ClickDetector.MouseClick:connect(clicked)
ASSUMING your game is Filtering Enabled, your problem would be in that you are trying to get the Mouse from a player in a Script which is Server side, but you can only get the mouse from a Local Script on the Client side. It works in Studio because Studio ignores Filtering Enabled and allows you to cross this boundary, while in a real server it would be respected and you would not be able to access that sort of data from the server side.
To fix this you would need to do all your mouse stuff on a Local Script on the client side, and then fire Remote Events/Functions to the Server side to move all the parts and objects around.
Capitalization matters
maybe the problem is instead of
playerSlot = PlayerSlot(player)
try
playerSlot = playerSlot(player)
I have no idea what this script even does, but since you mentioned that line, I am assuming this is the problem
The reason that this isn't working as you expect, is because you are using a ClickDetector
which is Server side
, but you are trying to access the player's Mouse
which is Client side
.
What this comes down to, is you aren't able to use both in the same script, as one needs to be used in a Script
, and the other a LocalScript
.
I won't be writing your whole script over for you, but hopefully I can point you in the right direction.
To make things easier, you should start off by moving things completely either on the Client
or on the Server
.
If you choose to stay on the server, you've lost the mouse and all of it's positioning. All you get to know is when someone clicks your click detector and who it was.
If you go on the Client, you ditch the click detector, however you can use useful things like mouse.Target
and determine if what you clicked is the door/clickable part by checking it's name or objects inside of it. This will allow you to also get it's mouse.Hit.p
and so on to do more math stuff.
--
With those 2 options, I would go with the client especially if you need the specific position the mouse clicked, and not just which part. This isn't a quick fix, I know, however I hope you can get going in the right direction from it.
Once you've layed down client code, you can use RemoteEvents or RemoteFunctions to handle things you don't trust the client with.