Hi everyone. I've been trying to make the CFrame tool (where you can move parts with the "arrow handles" and "rotation orbs") work with models for my personal use as I want to move and rotate models on an axis with a tool instead of dragging it around everywhere with the default move tool, like in ROBLOX studio.
I've been at this for hours and I did make some progress, but lost it because of ROBLOX Studio crashing when I was about to save my work (with no auto save...) Now I'm back at square one.
The hard part of making this is work is the fact that the tool is made to work with the mouse's Target, so I'd have to rewrite the code to make it so that it gets the model and make it able to be moved and rotated.
I have the following idea for a recursive function to get the root model of a group of parts/models:
function getRootModel(model)
if model.Parent == game.Workspace and model:IsA("Model") then
return model
elseif model.Parent ~= game.Workspace then
getRootModel(model.Parent)
elseif model.Parent == game.Workspace and not model:IsA("Model") then
return nil
end
end
EDIT: I've got the CFrame tool to work with models, now I am wondering why when I move the model, it goes in a completely different direction to where I want it to go. The script is below.
local Tool = script.Parent
enabled = true
local selectionBox
local arcHandles
local moveHandles
local selectedPose
local previousCFrame
local previousDistance
function getRootModel(model)
if model.Parent:IsA("Model") and model.Parent.Parent == game.Workspace then
return model.Parent
elseif not model.Parent:IsA("Model") and model.Parent.Parent ~= game.Workspace then
return getRootModel(model.Parent)
elseif not model.Parent:IsA("Model") and model.Parent.Parent ~= game.Workspace then
return nil
end
end
function onArcHandlesDown(normal)
print("handlesDown")
if selectedPose then
previousCFrame = selectedPose:GetPrimaryPartCFrame()
moveHandlesPart.Position = selectedPose.PrimaryPart.Position
moveHandlesPart.Size = selectedPose:GetExtentsSize()
end
end
function onArcHandlesDrag(axis, relativeAngle, deltaRadius)
if selectedPose then
local axisangle = Vector3.FromAxis(axis)
axisangle = axisangle * relativeAngle
selectedPose:SetPrimaryPartCFrame(previousCFrame * CFrame.Angles(axisangle.X, axisangle.Y, axisangle.Z))
local x, y, z = selectedPose:GetPrimaryPartCFrame():toEulerAnglesXYZ()
print(math.floor(math.deg(x)), math.floor(math.deg(y)), math.floor(math.deg(z)))
moveHandlesPart.Position = selectedPose.PrimaryPart.Position
moveHandlesPart.Size = selectedPose:GetExtentsSize()
end
end
function onMoveHandlesDown(normal)
print("handlesDown")
if selectedPose then
previousDistance = 0
moveHandlesPart.Position = selectedPose.PrimaryPart.Position
moveHandlesPart.Size = selectedPose:GetExtentsSize()
end
end
function onMoveHandlesDrag(normal, distance)
if selectedPose then
local delta = distance - previousDistance
translation = CFrame.new(Vector3.FromNormalId(normal) * delta)
selectedPose:SetPrimaryPartCFrame(selectedPose.PrimaryPart.CFrame * translation)
previousDistance = distance
print(selectedPose.PrimaryPart.Position)
moveHandlesPart.Position = selectedPose.PrimaryPart.Position
moveHandlesPart.Size = selectedPose:GetExtentsSize()
end
end
function onButton1Down(mouse)
print("3DButtonDown")
selectionBox.Adornee = nil
arcHandles.Adornee = nil
moveHandles.Adornee = nil
if mouse.Target ~= nil then
selectedPose = getRootModel(mouse.Target)
selectionBox.Adornee = mouse.Target
arcHandles.Adornee = mouse.Target
moveHandlesPart.Position = getRootModel(mouse.Target).PrimaryPart.Position
moveHandlesPart.Size = getRootModel(mouse.Target):GetExtentsSize()
moveHandles.Adornee = moveHandlesPart
end
end
function onEquippedLocal(mouse)
local character = script.Parent.Parent
local player = game.Players:GetPlayerFromCharacter(character)
mouse.Icon ="rbxasset://textures\\DragCursor.png"
mouse.Button1Down:connect(function() onButton1Down(mouse) end)
selectionBox = Instance.new("SelectionBox")
selectionBox.Color = BrickColor.new("New Yeller")
selectionBox.Adornee = nil
selectionBox.Parent = player.PlayerGui
arcHandlesPart = Instance.new("Part")
arcHandlesPart.Name = "ArcHandlesProxyPart"
arcHandlesPart.Size = Vector3.new(2,2,2)
arcHandlesPart.Parent = player.PlayerGui
moveHandlesPart = Instance.new("Part")
moveHandlesPart.Name = "MoveHandlesProxyPart"
moveHandlesPart.Size = Vector3.new(2,2,2)
moveHandlesPart.Parent = player.PlayerGui
moveHandles = Instance.new("Handles")
moveHandles.Style = Enum.HandlesStyle.Movement
moveHandles.Color = BrickColor.new("Lime green")
moveHandles.Adornee = nil
moveHandles.MouseDrag:connect(onMoveHandlesDrag)
moveHandles.MouseButton1Down:connect(onMoveHandlesDown)
moveHandles.Parent = player.PlayerGui
arcHandles = Instance.new("ArcHandles")
arcHandles.Color = BrickColor.new("Really black")
arcHandles.Adornee = nil
arcHandles.Axes = Axes.new(Enum.Axis.X, Enum.Axis.Y, Enum.Axis.Z)
arcHandles.MouseDrag:connect(onArcHandlesDrag)
arcHandles.MouseButton1Down:connect(onArcHandlesDown)
arcHandles.Parent = nil
mouse.KeyDown:connect(function(key)
if key:lower() == "r" and moveHandles.Parent ~= nil then
moveHandles.Parent = nil
arcHandles.Parent = player.PlayerGui
elseif key:lower() == "r" and arcHandles.Parent ~= nil then
moveHandles.Parent = player.PlayerGui
arcHandles.Parent = nil
end
end)
end
function onUnequippedLocal()
selectionBox:Remove()
arcHandles:Remove()
moveHandles:remove()
end
Tool.Equipped:connect(onEquippedLocal)
Tool.Unequipped:connect(onUnequippedLocal)
Thanks in advance!

3 comments
I took a look at the CFrame tool awhile ago and it's broken because of one line: 48. Should be 'selectedPose.CFrame = selectedPose.CFrame * translation' I know this doesn't help but I can't answer this question atm, so look up 'SetPrimaryPartCFrame' on wiki(:
I did but I realized some models don't have PrimaryParts so it would break. I could make one, I just need to grab the model I want from my old pc as I just transitioned a few days ago to a new pc.
Okay, I've got the tool to work with models. The rotation works great but when I switch to moving the model (I made a part where it changes between rotation and moving), the movement goes in a different direction from where I want it to go, depending on the model's location. I'll replace the old CFrame tool script with my one.