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:
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!
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)```