Hello, I’m currently doing game when I need some grab system, So I tried to remake the one that have Lumber Tycoon 2, But the basic systems works like detection of keys , But the moving part I can’t figure out how it can be done,
My version:
So if you play it and you will come near to the part and click on it it will works but not as original Lumber Tycoon 2 system
My code
-- Server Script
local remotes = game.ReplicatedStorage.GrabRemotes
game.Players.PlayerAdded:Connect(function(plr)
local GrabbingItem = Instance.new("StringValue",plr)
GrabbingItem.Name = "CurrentGrabbing"
local IsGrabbing = Instance.new("BoolValue",plr)
IsGrabbing.Name = "IsGrabing"
IsGrabbing.Value = false
end)
local AllowedModels = {
"TestPart"
}
remotes.initGrabbing.OnServerEvent:Connect(function(plr,Item)
if table.find(AllowedModels,Item.Name) ~= nil then
print("Succesfully start grabbing init!")
plr.CurrentGrabbing.Value = Item.Name
plr.IsGrabing.Value = true
end
end)
remotes.resetGrabbing.OnServerEvent:Connect(function(plr)
print("Sucesfully reseted grabbing values")
plr.CurrentGrabbing.Value = ""
plr.IsGrabing.Value = false
end)
remotes.CheckIfTrue.OnServerInvoke = function(plr,Item)
if table.find(AllowedModels,Item.Name) ~= nil then
return true
else
return false
end
end
remotes.IsGrabbing.OnServerInvoke = function(plr)
if plr.IsGrabing.Value == true then
return true
else
return false
end
end
remotes.MoveItem.OnServerEvent:Connect(function(plr,pos)
if plr.IsGrabing.Value == true then
workspace[plr.CurrentGrabbing.Value].Position = pos + Vector3.new(0,2,0)
end
end)
I don’t know how you calculate the position on the client, but I believe it could be a good idea to use an AlignPosition constraint for moving instead of directly setting the position. You should also add a limit to how far away the dragged part can be from the player.
Server:
local remotes = game.ReplicatedStorage.GrabRemotes
local function createAlignPos(part)
local alignPos = Instance.new("AlignPosition")
alignPos.MaxForce = 10000
alingPos.Responsiveness = 200
local attach0, attach1 = Instance.new("Attachment"), Instance.new("Attachment")
alignPos.Attachment0, alignPos.Attachment1 = attach0, attach1
attach0.Parent, attach1.Parent = workspace.Terrain, part
alignPos.Parent = part
return alignPos
end
local function destroyAlignPos()
alignPos.Attachment0:Destroy()
alignPos.Attachment1:Destroy()
alignPos:Destroy()
end
game.Players.PlayerAdded:Connect(function(plr)
local GrabbingItem = Instance.new("StringValue",plr)
GrabbingItem.Name = "CurrentGrabbing"
local IsGrabbing = Instance.new("BoolValue",plr)
IsGrabbing.Name = "IsGrabing"
IsGrabbing.Value = false
end)
local AllowedModels = {
"TestPart"
}
remotes.initGrabbing.OnServerEvent:Connect(function(plr,Item)
if table.find(AllowedModels,Item.Name) ~= nil then
print("Succesfully start grabbing init!")
createAlignPos(item)
plr.CurrentGrabbing.Value = Item.Name
plr.IsGrabing.Value = true
end
end)
remotes.resetGrabbing.OnServerEvent:Connect(function(plr)
print("Sucesfully reseted grabbing values")
destroyAlignPos(plr.CurrentGrabbing.Value.AlignPosition)
plr.CurrentGrabbing.Value = ""
plr.IsGrabing.Value = false
end)
remotes.CheckIfTrue.OnServerInvoke = function(plr,Item)
return table.find(AllowedModels,Item.Name) ~= nil
end
remotes.IsGrabbing.OnServerInvoke = function(plr)
return plr.IsGrabbing.Value
end
remotes.MoveItem.OnServerEvent:Connect(function(plr, pos)
if plr.IsGrabing.Value == true then
plr.CurrentGrabbing.Value.AlignPosition.Attachment0.Position = pos
end
end)
Client side position calculation
local Players = game:GetService("Players")
local ITEM_MAX_DISTANCE = 20
local plr = Players.LocalPlayer
local mouse = plr:GetMouse()
local raycastParams = RayCastParams.new()
raycastParams.FilterType = Enum.FilterType.BlackList
local function calculatePos() -- send the return value of this to the server
raycastParams.FilterDescendantsInstances = {plr.Character, plr.CurrentGrabbing.Value}
local unitRay = mouse.UnitRay
local origin = unitRay.Origin
local directionWithMagnitude = unitRay.Direction*ITEM_MAX_DISTANCE
local rayCastResult = workspace:RayCast(origin, directionWithMagnitude, raycastParams)
if rayCastResult then
return rayCastResult.Position
else return origin+directionWithMagnitude
end
end
I made one of these systems a while back for one of my games and you should use BodyPositions to move the part. You can use math.clamp to prevent the part from moving too far away from the player. If the game is multiplayer, make sure to set the network ownership of the part to the server to avoid glitching.