Resizing multiple parts in the same direction with different rotation

Hey there, I have a building game in Roblox which is called “Wubby” and it has a resize tool inside of it. The resize tool supports multiple selection, however, if a non-parallel rotated block with the first block (like 0, 0, 0 vs 0, 90, 0) is inside the multiple selection, it’ll just resize that block towards its own axis instead of following the first part’s axis.

What I’ve been searching for is something like this:
0bf564c12e27a01fa2814ecad30c5e4e84099c27

btw, the “ResizeObject” mode you can see in this gif is nearly the same thing that is happening to me, I want to make it work like “ResizeWorld”

Since my resize tool system works with normals, what I’ve been looking for is something like this:

(I’m not really good explaining, haha) I was looking for someway (WITHOUT RAYCASTING, I know how to use raycasting but I don’t want to use raycasting for this case because of performance issues) to adapt a normal to another part’s orientation or CFrame. In the first segment of that image you can see a part pointing to one direction, and in the next one you can see a rotated part which also keeps the same direction, however it’s using a different normal to be in the same direction as the first part.

Any help is welcome, I’ve been 3 days straight searching a solution for this and I haven’t found anything that suits my needs!

Hiiii ger :3
The first thing that showed up when I searched for “global resizing roblox” was the solution of what you need: How can I scale or size a part on a global axis, instead of local, via script - #4 by SalmonJumped

If that’s not what you want, please let me know

1 Like

If I recall correctly, CFrame has a built-in function called VectorToObjectSpaxe that can converts your normal vector relative to the part’s CFrame

Hey I’ve looked at the link you sent and I don’t quite understand that answer. I need to calculate 2 things when resizing: the CFrame and the size, that answer only gives me the size, and also has an example that makes no sense whatsoever (why are you getting the part’s size to then apply the method you’re trying to showcase?)

Still, thank you for answering because I completely forgot WorldSpaces and ObjectSpacess were a thing!

Hey, I forgot to respond to this long time ago. Someone gave me this script through DMs that completely fixes my problem:

		local deselectCallback


		local origin = {}
		
		local faceList = {
			Enum.NormalId.Back;
			Enum.NormalId.Bottom;
			Enum.NormalId.Front;
			Enum.NormalId.Left;
			Enum.NormalId.Right;
			Enum.NormalId.Top;
		}
		local faceVectors = {}
		for index, face in next, faceList do
			faceVectors[index] = Vector3.FromNormalId(face)
		end
		
		OnToolSelect[Tool] = function(tool,vars)

		
			local first
			local cinc
			local inc
			local rdis = 0
			local lastDist = 0
			local fNorm
			
			Event[tool].Down = OverlayHandles.MouseButton1Down:Connect(function(face)
				lastDist = 0
				first = ToolSelection[1]
				for k in next,origin do
					origin[k] = nil
				end
				fNorm = first.CFrame:vectorToWorldSpace(nid(face))
				DisplayInfo(true, Menu, 0)
				for _,part in next,ToolSelection do
					if not IsA(part, 'Terrain') then
						local partCFrame = part.CFrame
						local rIndex, rDot = 1, -inf
						for i, test in next, faceVectors do
							local td = part.CFrame:vectorToWorldSpace(test):Dot(fNorm)
							if td > rDot then
								rDot = td
								rIndex = i
							end
						end
						local faceObj = faceList[rIndex]
						local isTruss = IsA(part, 'TrussPart')
						origin[part] = {
							partCFrame;
							part.Size;
							isTruss;
							isTruss and 2 or MIN_SIZE;
							FACE_MULTIPLIER[faceObj];
							FACE_COMPONENT[faceObj];
							faceVectors[rIndex];
						}
					end
				end
				cinc = vars.Increment
				inc = Snap(cinc,1)
				if inc == 0 then
					inc = 1
				end

				rdis = 0
				function deselectCallback()
				end
			end)

			
			Event[tool].Drag = OverlayHandles.MouseDrag:Connect(function(face, distance)
				local ddis = Snap(distance, cinc)
				if ddis == lastDist then
					return
				end
				lastDist = ddis
				for part, info in next, origin do
					local sz, isTruss, ffm, face_mult, face_size, face_vec = info[2], info[3], info[4], info[5], info[6], info[7]
					local dis = distance*face_mult
					local mult = Snap(dis, isTruss and inc*ffm or cinc)
					local fsize = sz[face_size]
					local mod = fsize + mult*face_mult < ffm and face_vec*((ffm - fsize)*face_mult) or face_vec*mult
					part.Size = sz + mod
					part.CFrame = info[1]*cf(mod*face_mult/2)
					if part == first then
						rdis = mod.Magnitude
					end
				end
			end)```

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