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!
Use this plugin while using Edit mode in your place. It allows you to do a bunch of stuff with models, including scaling them as well as moving them. It also works with individual parts.