Making union split into two

Hello, so I basically want to negate a part but make the union two separate pieces instead of one union.

For example

This part has been negated and is now a union. But as you can see, visually speaking, there are two parts, the top and the bottom. I want to know how I can unanchor the top part so it falls to the ground. I’ve though about getting the position of the cut and replacing the top part with a new part with sizes and positions based on the cut.

This post was placed in the scripting category as the negate process has been done in a script.

Any ideas? Thanks.

It wouldn’t work for anything that isn’t uniform in size and shape but you could just create 2 new parts which mimic the negation. Unfortunately, because of how unions work, I don’t think that’s possible through unioning (although I could be wrong).

you cant do that with unions as they are only for visual purpose and their physics wont act like 2 different pieces

Any ideas on how I can mimic the negation using parts?

It depends on what you want to achieve but it would probably look something like this:

function slicePart()
	local newpart1 = part:Clone()
	newpart1.Name = "NewPart1"
	newpart1.Parent = workspace
	newpart1.Size = part.Size - Vector3.new(0,part.Size.y/2,0) 
-- If you wanted one part to be larger than the other part you could just change the amount the part size is divided by.
	newpart1.Position = (part.Position+Vector3.new(0,part.Size.y/4,0))
-- You can change the position of the part (to make it further away from the second part or closer), currently they are touching.
	newpart1.Anchored = false

	local newpart2 = part:Clone()
	newpart2.Name = "NewPart2"
	newpart2.Parent = workspace
	newpart2.Size = part.Size - Vector3.new(0,part.Size.y/2,0)
	newpart2.Position = (part.Position+Vector3.new(0,-part.Size.y/4,0))
	newpart2.Anchored = true
	
	part:Destroy()
end

slicePart()
1 Like

Just duplicate the part, negate the top off the duplicate and the bottom off the original.

1 Like

@ramdom_player201 has the easiest option. I also wrote this function for splitting along an axis if you don’t want to union parts:

local function Split(part: BasePart, axis: Enum.Axis, studs: number)
	-- comments are examples when axis is Enum.Axis.X
	
	local first = part:Clone()
	local second = part:Clone()
	
	-- (1, 0, 0) for x-axis example
	local axisVec = Vector3.FromAxis(axis)
	
	-- (0, 1, 1)
	local axisMask = Vector3.new(1, 1, 1) - axisVec
	
	-- can multiply this by axisVec to get (studs, 0, 0)
	local studVec = Vector3.new(studs, studs, studs)
	
	-- (0, first.Size.Y, first.Size.Z) + (studs, 0, 0)
	first.Size = first.Size * axisMask + studVec * axisVec
	
	-- second.Size - (studs, 0, 0)
	second.Size = second.Size - studVec * axisVec
	
	-- vector pointing along part's x axis for example
	local worldAxis = part.CFrame:VectorToWorldSpace(axisVec)
	
	-- (part.Size.X, 0, 0)
	local sizeAlongAxis = part.Size * axisVec
	
	-- part.Size.X
	local len = sizeAlongAxis.X + sizeAlongAxis.Y + sizeAlongAxis.Z
	
	first.CFrame = part.CFrame + worldAxis * (studs - len) / 2
	second.CFrame = part.CFrame + worldAxis * studs / 2 
	
	-- can remove, just for testing
	first.BrickColor = BrickColor.Random()
	second.BrickColor = BrickColor.Random()
	
	-- could change this to just return instead of parenting first
	first.Parent = workspace
	second.Parent = workspace
	
	return first, second
end

-- usage example

local part = workspace.Part

while true do
	for _, axis in pairs({Enum.Axis.X, Enum.Axis.Y, Enum.Axis.Z}) do
		-- stolen from above function just for random generation
		local axisVec = Vector3.FromAxis(axis)
		local sizeAlongAxis = part.Size * axisVec
		local len = sizeAlongAxis.X + sizeAlongAxis.Y + sizeAlongAxis.Z
		
		local a, b = Split(workspace.Part, axis, math.random() * len)
		part.Transparency = 1
		
		wait(1)
		
		a:Destroy()
		b:Destroy()
		part.Transparency = 0
	end
end

2 Likes

Both ideas are very useful, thanks very much!