Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why do I get this error? Please read before reviewing code.

Asked by 5 years ago

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)

3 answers

Log in to vote
0
Answered by 5 years ago

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.

0
Got it, let me try that right now. I thought it was that but wanted to make sure because I didn't want to do un needed programming. I've restarted this script 3 times because some things weren't the way I wanted them to be lol. joshmatt1245 5 — 5y
Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

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

0
Like I said, read everything. What that variable does is it calls the PlayerSlot function sending the player variable. Then, playerSlot sets it self as the return value of the PlayerSlot function. joshmatt1245 5 — 5y
0
"Read everything" how about you explain the code to us instead? Reading the code won't mean we'll understand what you're trying to accomplish well enough that we will be able to help you. T0XN 276 — 5y
0
On the very last line :Connect instead of connect??? I don't think there is much of a difference though greatneil80 2647 — 5y
Log in to vote
0
Answered by
amanda 1059 Moderation Voter
5 years ago
Edited 5 years ago

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.

0
Here, go down to "Server to Client", it sais that the client does NOT have information the server doesn't have. That means, even if I were to do player:GetMouse() or game.Players[player.Name]:GetMouse(), they would both do the same thing. Get the mouse of the player specified. joshmatt1245 5 — 5y
0
Please read the very top of THIS article: http://wiki.roblox.com/index.php?title=API:Class/PlayerMouse "Each Player has a PlayerMouse which acts exactly the same as the Mouse object. The only way to access this object is with the GetMouse method of the Player object from a LocalScript." Hence, you cannot access it in a server script because that kind of user input is client side. amanda 1059 — 5y

Answer this question