I was just making a game called "Mayor Sphereoid's Community Place" and I was trying to create build tools. To add some context to why I'm not using the Tool instance, the characters are not humanoids but they are balls with custom controls and a custom camera, meaning that most things compatible with a normal Roblox avatar won't work with my characters.
In my game, there is: A remote function, PartFunction, used to run part functions as a client A remote event, PartMod, used to change values of parts as a client A custom configuration folder put inside a player instance containing the currently held tool
These scripts worked a minute ago and I barely changed anything!
ServerScriptService PartMod (Script)
game.ReplicatedStorage:WaitForChild("PartMod").OnServerEvent:Connect(function(player, part, attr, value, operation)
if operation == "add" then
part[attr] = part[attr] + value
elseif operation == "multiply" then
part[attr] = part[attr] * value
else
part[attr] = value
end
end)
game.ReplicatedStorage:WaitForChild("PartFunction").OnServerInvoke = function(player, part, func, ...)
if func == "Clone" then
local result = part:Clone()
result.Parent = game.ReplicatedStorage.StoredParts
result.Name = string.format("%x", math.random(0, 15)) .. "x" .. string.format("%x", player.UserId)
return {name=part.Name, key=result.Name}
elseif func == "Destroy" then
part:Destroy()
elseif func == "Resize" then
local testPart = part:Clone()
testPart:Resize(...)
if testPart.Size.X <= 0.05
or testPart.Size.Y <= 0.05
or testPart.Size.Z <= 0.05 then
testPart:Destroy()
return false
end
testPart:Destroy()
return part:Resize(...)
end
end
StarterPlayerScripts ToolControl (LocalScript)
local player = game.Players.LocalPlayer
local config = player:WaitForChild("Configuration")
local mouse = player:GetMouse()
local rs = game.ReplicatedStorage
local partMod = function(...) rs.PartMod:FireServer(...) end
local partFunc = function(...) return rs.PartFunction:InvokeServer(...) end
-- partMod(part, attr, val, [operation])
-- partFunc(part, func, ...)
local part = nil
local handles = Instance.new("Handles", player.PlayerGui)
local ogMoveDistance = 0
local ogResizeDistance = 0
local function round(x, y)
return math.floor(x / y + 0.5) * y
end
local function handleHandlerInit()
ogMoveDistance = 0
ogResizeDistance = 0
end
local function handleHandler(face, distance)
local inc = 0.25
if face == Enum.NormalId.Top or face == Enum.NormalId.Bottom then
inc = inc * 1.2
end
-- Resize
if config.Tool.Value == "resize" then
distance = distance / 4
local delta = distance - ogResizeDistance
if math.abs(delta) >= inc then
local sizeDelta = math.floor(delta / inc + 0.5) * inc
print(sizeDelta)
if partFunc(part, "Resize", face, sizeDelta) then
ogResizeDistance = distance
end
end
-- Move
elseif config.Tool.Value == "move" then
local delta = distance - ogMoveDistance
if math.abs(delta) >= inc then
local sizeDelta = math.floor(delta / inc + 0.5) * inc
partMod(part, "CFrame", CFrame.new(Vector3.FromNormalId(face) * sizeDelta), "multiply")
ogMoveDistance = distance
end
end
end
handles.Name = "BToolHandles"
handles.MouseButton1Down:Connect(handleHandlerInit)
handles.MouseDrag:Connect(handleHandler)
game:GetService("UserInputService").InputBegan:Connect(function(key)
if key.UserInputType == Enum.UserInputType.MouseButton1
and key.UserInputState == Enum.UserInputState.Begin then
if mouse.Target
and mouse.X < mouse.ViewSizeX - 90 then
if mouse.Target.Parent == workspace.BuildingParts then
-- Clone tool
if config.Tool.Value == "clone" then
local info = partFunc(mouse.Target, "Clone")
part = rs.StoredParts:FindFirstChild(info.key)
partMod(part, "CFrame", CFrame.new(0, part.Size.Y, 0), "multiply")
partMod(part, "Name", info.name)
if not part:FindFirstChild("Ownership") then
local ownership = Instance.new("IntValue", part)
ownership.Name = "Ownership"
ownership.Value = player.UserId
end
partMod(part, "Parent", workspace.BuildingParts)
end
-- Select tool
if config.Tool.Value == "select"
and not mouse.Target.Locked
and part.Ownership then
if part.Ownership.Value == player.UserId then
handles.Adornee = part
end
-- Destroy tool
if config.Tool.Value == "destroy"
and not mouse.Target.Locked
and part:FindFirstChild("Ownership") then
if part.Ownership.Value == player.UserId then
partFunc(mouse.Target, "Destroy")
end
end
end
-- Remove unused handles
elseif config.Tool.Value == "select"
and mouse.X < mouse.ViewSizeX - 90 then
handles.Adornee = nil
end
end
end)
This is just so weird! Please help immediately!
NOTES:
I wanted to make it so that parts can't go to 0.05x0.05x0.05 size
I have a control panel on the right which I don't want anyone to click through (hence mouse.X < mouse.ViewSizeX - 90)
There are no errors that appear!
Edit: There is an error that appears, actually. Look at my answer for more info.
