Cutting/Slicing parts on client

Im trying to make a laser that runs on client and and then it runs through a part with a raycast it cuts that part along that line. On the server this works, but two large problems come up when I try to get it to work on client. 1. Subtract async can only be done on server. 2. I cant send parts or unions to the server script to do the cutting because they are client-sided. Im not sure were to go with this. Any workaround I could try to get it to work? (I tried using the cframe of part and then making a copy on the server, but since it also needs to be able to cut unions this method probably wont work)

So from what i gather, you want to use a client script to cut a part, and only have that part be cut on the client side only. However, you are getting issues because subtract async can only be done on server.

So how you might be able to do this is to have a localScript to raycast and calculate information on how you want a part to be cut, it sends this information to a serverScript. This serverScript will then perform the subtract async on the parts, and then send the newly created union back to the client so the client can then replace the old part with the union part it got from the server.

Might not be the best way to do it, but let me know how it goes for you ^^

Edit: So i’ve been messing around with my idea and come up with a sort of working prototype for client only subtract async. Of course, you’ll need to modify it to suit your own needs and it’s far from perfect.

Prototype Code

First, my really bad, wierd hierarchy for this prototype. (obviously you should put your scripts in a much better place than this but this was a quick test so i didn’t.)
image

Server Script

local model = script.Parent

local part = model:WaitForChild("Part")
local remover = model:WaitForChild("Remover")

local remote = model:WaitForChild("RemoteEvent")

local function cut()
	local success, newSubtract = pcall(function()
		return part:SubtractAsync({remover})
	end)
	
	if success and newSubtract then
		newSubtract.Position = part.Position
		newSubtract.Parent = game:GetService("ReplicatedStorage")
		
		print("fire client")
		remote:FireAllClients(newSubtract)
	end
	
end

wait(3) -- Give time for my client script to load and start running

cut()

Local Script

local model = script.Parent

local part = model:WaitForChild("Part")
local remover = model:WaitForChild("Remover")

local remote = model:WaitForChild("RemoteEvent")

remote.OnClientEvent:Connect(function(newSubtract)
	print("message recieved")
	newSubtract.Parent = workspace
	
	part:Destroy()
	remover:Destroy()
end)

(You’ll need to work out for yourself what you want to do with the server-side unions left over in ReplicatedStorage after it’s done)

1 Like

I was trying to use a remote function. The problem with your server script you have is its accessing the parts. The parts I have for laser only exist on client, which is why I cant send it to SubtractAsync()

Sorry had to edit because i accidentally posted it half-finished :stuck_out_tongue:

Ah, i see. That’s certantly a tricky one then. I know you’ve tried using the cframe of the parts to make a copy on the server, but I think that might be the method you’ll need to use. It’s so annoying we can’t send part info across the server-client boundary.

I managed to get part info from client to server by storing all the part’s important properties (so ones that will affect how the union will turn out) in a list, and then sending that to the server so it can re-create the part/s.

Sending data to server

Client Script

local model = script.Parent
local remote = model:WaitForChild("RemoteEvent")

local properties = {
	-- A list of all the important properties you might want to carry over
	-- Obviously i dont know what properties are important for your scripts
	-- Probably get issues with performance so only carry over properties you need,
	-- anything else can be be set on the union part back on the client side
	"Color",
	"Material",
	"Transparency",
	"Name",
	"Size",
	"CFrame",
	"CanCollide",
	"Anchored",
	"Shape",
	"Parent"
}

local function partToData(part)
	local dataPart = {}
	for _, propertyName in ipairs(properties) do
		dataPart[propertyName] = part[propertyName]
	end
	return dataPart
end

local function multiplePartsToData(array)
	local newArray = {}
	for _, part in ipairs(array) do
		table.insert(newArray,partToData(part))
	end
	return newArray
end

local part1 = Instance.new("Part")
part1.Anchored = true
part1.BrickColor = BrickColor.new("Really red")
part1.Name = "ClientPart1"
part1.Parent = workspace

local part2 = Instance.new("Part")
part2.Anchored = true
part2.Name = "ClientPart2"
part2.Parent = workspace

remote:FireServer(multiplePartsToData({part1,part2}))

And then you’ll need to re-create the new parts on the server ^^

local model = script.Parent
local remote = model:WaitForChild("RemoteEvent")

local function recreatePartsFromClient(partsArray)
	for _, dataPart in ipairs(partsArray) do -- For every part in the array
		local part = Instance.new("Part")
		for propertyName, propertyValue in pairs(dataPart) do -- Loop through properties and add them to the new part
			print(propertyName)
			part[propertyName] = dataPart[propertyName]
		end
		
	end
end

remote.OnServerEvent:Connect(function(plr,clientParts)
	recreatePartsFromClient(clientParts)
end)

This along with the other scripts i sent should be able to work together to do what you need. And you have the right idea with using a remoteFunction to tie it all together. I need to catch some sleep so I won’t be able to respond again for a while.

I have tried this, and although it works with parts, if I have a part that been cut once aready and is now a union. I have no way of cutting it again. Edit that why Im set on trying to find a way to send the instance, but I dont think its possible so Im stuck.

Is it possible to undo the union, send the raw parts to the server so it can re-build the union with the extra cuts maybe? If not then yeah unfortunately I also ran out of ideas :confused: You might have to try a different way of cutting parts

Edit: Or maybe not undo the union, but store the raw parts it’s made out of and then send that.
So you’ll have two versions of each part on the client - A hidden version of just the parts unmerged, and then a version the player can see as one big union.

1 Like


This was said in 2019 and still no client sided geometry

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.