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

X and Y max distance from player torso?

Asked by 7 years ago

Hi there! Currently I am developing a part dragger script! I want to set it so the player cannot move the part too far away from the torso of the player. How would I set a Y max distance and a X max distance from the player torso? Currently when dragging a part, it lets it go an infinite distance but I would like to narrow that down to something reasonable.

plr = game.Players.LocalPlayer
mouse = plr:GetMouse()
target = {}

script.Parent = game.StarterPlayer.StarterPlayerScripts
function click()
    if mouse.Target then
        if mouse.Target:IsA("UnionOperation") and mouse.Target.Locked == false and ((plr.Character:WaitForChild('Torso').Position - mouse.Target.Position).magnitude < 10) then
            target.part = mouse.Target
            target.anchored = target.part.Anchored
            target.part.Anchored = true
            dim = true
            mouse.Move:connect(function()

                if dim then
                    target.part.CFrame = CFrame.new(
                        mouse.Hit.X,target.part.CFrame.Y,mouse.Hit.Z)
                elseif not dim then
                end

            end
            )
            mouse.Button1Up:connect(function()
                dim = false
                 target.part.Anchored = target.anchored

            end)
        end
    end
end
mouse.Button1Down:connect(click)

1 answer

Log in to vote
3
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
7 years ago
Edited 7 years ago

Making the code you have better

Connecting events inside other event handlers is usually wrong. In this code, every time you click, you start another loop that waiting for Move and Button1Up events.

You refer to mouse.Target 5 times; just make a variable. (This also seems to be necessary in some strange situations because mouse.Target can be re-computed within a single frame)

dim should not be its own variable, it should be a part of target. The simplest way is to just make target nil whenever you don't have a target (since nil indicates absence this is very natural)

Don't use silly abbreviations like plr, just type the full word out, player. ROBLOX can help you autocomplete words and it's easier to read and type.

Don't use == false and == true, just use the plain boolean (with not if appropriate).

Clean code reads like well written prose

The key to writing good code is just writing exactly what you intend.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local target = nil -- initially, there is no target

-- RETURNS whether or not `point` is near the player
local function playerIsNear(point)
    assert(typeof(point) == "Vector3")
    local character = player.Character
    if not character then
        -- the player has no character, and so is near nothing
        return false
    end
    -- R15 doesn't have a Torso; use HumanoidRootPart
    -- for the "central" part of the player
    local root = character:FindFirstChild("HumanoidRootPart")
    if not root then
        -- the player has no root part (is probably dead)
        return false
    end
    return (root.Position - point).magnitude < 10
end

-- When the player clicks on an unlocked Union,
-- make that union the `target`
-- (noting whether or not it was anchored)
-- and anchor it
function onClick()
    -- When the player clicks...
    local union = mouse.Target
    if union then
        -- ... on a ...
        if union:IsA("UnionOperation") and not union.Locked then
            -- ...not-Locked Union ...
            if playerIsNear(union.Position) then
                -- ... that is near the player

                -- Make this the new union,
                -- noting whether or not it was anchored
                target = {
                    part = union,
                    wasAnchored = union.Anchored,
                }

                -- Anchor the union.
                union.Anchored = true
            end
        end
    end
end

-- When the player moves the mouse,
-- move the target (if any) to where they are pointing
function onMove()
    -- When the player moves the mouse,
    if target then
        -- If there is a target,
        -- Move the target part to where they are pointing
        local pointing = mouse.Hit.p
        target.part.CFrame = CFrame.new(pointing.x, target.part.Position.y, pointing.y)
    end
end

-- When the player releases the mouse button,
-- stop "targeting" any part (if you were)
-- and unanchor it (if it was originally unanchored)
function onRelease()
    if target then
        -- If the player was targeting something...

        -- Unanchor it (if it was originally unanchored)
        target.part.Anchored = target.wasAnchored

        -- Stop targeting the part
        target = nil
    end
end

-- Make the events fire when you want them to
mouse.Button1Down:Connect(onClick)
mouse.Button1Up:Connect(onRelease)
mouse.Move:Connect(onMove) -- Heartbeat may be better

Notice how the comments say exactly what you want to do? Notice how similar the code is to the comments?

Making the change

You want to change

When the player moves the mouse, move the target (if any) to where they are pointing

to be

When the player moves the mouse, move the target (if any) to where they are pointing IF THEY ARE POINTING TO SOMETHING NEAR

Well, just go to that part of the code and add it:

function onMove()
    -- When the player moves the mouse,
    if target then
        -- If there is a target,
        -- Move the target part to where they are pointing
        local pointing = mouse.Hit.p
        if playerIsNear(pointing) then
            -- ... only if they are pointing near themself
            target.part.CFrame = CFrame.new(pointing.x, target.part.Position.y, pointing.y)
        end
    end
end

Why is the code longer?

Your code is 31 lines (27 are not blank).

My code is 85 lines. But:

  • 10 are blank lines (as opposed to 4 in yours)
  • 28 are comments (as opposed to 0 in yours)
  • 1 is an assert

Which only leaves 46 lines.

  • 6 of which address error conditions your code doesn't (in playerIsNear)
0
Thanks you for helping me resolve my issue. When testing out your script though, it seemed to not be able to move from the Y axis. So when dragging the brick, it would remain on the same Y coordinate. BunnyFilms1 297 — 7y
0
That's how your original code was written, so I assumed you wanted that. BlueTaslem 18071 — 7y
0
Why have lines 9 and 16 both different variables? Why not just check with one if statement w/o the variables, since they're not going to be used any other way (outside the function), and are used only for that purpose? Just wonderin'. e-e TheeDeathCaster 2368 — 7y
0
To be clear and have short lines. IMO, it's confusing (and error-prone) to re-compute a value rather than save the value to a variable. BlueTaslem 18071 — 7y
Ad

Answer this question