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)
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).
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?
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
Your code is 31 lines (27 are not blank).
My code is 85 lines. But:
assert
Which only leaves 46 lines.
playerIsNear
)