How to move a model using CFrame with NO primary part

  1. What do you want to achieve? I am trying to make a building tool

  2. What is the issue? I am trying to move a model with CFrame but with NO primary part whilst keeping welds but most solutions I found were either :Move() or :SetPrimaryPartCFrame()

  3. What solutions have you tried so far? most solutions I found were either :Move() or :SetPrimaryPartCFrame(). Move() uses Vector3 and most of the time teleports ontop of a roof. :SetPrimaryPartCFrame() requires a primary part to work.

If you know how to move a model to a CFrame whilst keeping welds without a primary part please let me know!

If all parts/meshes are welded to an unique “root” part inside the model, that would be your “primary part” no matter if its not stated as Primary Part in the Model’s properties, you can just change the CFrame of that “root” part that is carrying all the welds.
rootPart.CFrame = rootPart.CFrame * CFrame.new(0,10 0)
But, if you already have a “root” part of the model which welds all other meshes and parts, then turning it into the primary part would be a good idea

function move(model, _cf)
	local cf = model:GetBoundingBox()
	local prim = Instance.new("Part", model)
	prim.Name = "PrimaryPart"
	prim.CFrame = cf
	model.PrimaryPart = prim
	for i, v in next, model:GetDescendants() do
		if (not v:IsA("BasePart")) then continue end
		local w = Instance.new("WeldConstraint", prim)
		w.Part0 = prim
		w.Part1 = v
	end
	model:SetPrimaryPartCFrame(_cf)
	prim:Destroy()
end

move(amodel, CFrame.new(1,1,1))

The problem with that is that its creating NEW welds and again I have mentioned I cant use :SetPrimaryPartCrame() due to requiring a primary part.

The problem is that my model doesn’t carry welds in one part.

so what? it creates a primary part for you

The welds could be in many parts no need to have them all in one part, but theres not a root part that is connected to all meshes and parts? All parts are radomly connected to each others?

1 Like

You might want to look into Model:PivotTo(), this doesn’t require a primary part and it should just go to the child with the highest root priority, or the center of the bounding box of the model.

Personally haven’t tried it with welds while it’s under physics but this is just one of the other options asides manually building your own coordinate translator for it. Also, you can probably check out the documentation page for models as well.

4 Likes

A group can be moved, using PivotTo, and it doesn’t require a primary part.

I would still use MoveTo(). Just use an offset. For example:
model:MoveTo(goal.Position + Vector3.new(0,3,0)) – Vector3.new() is the offset.

PivotTo() uses CFrame.
model:PivotTo(CFrame.new(goal.Position) + Vector3.new(0,3,0)) – add the Vector3.new if you need an offset, if not, just the CFrame.new()

You can also do:
model:PivotTo(TheCFrame)

1 Like

The issue with :MoveTo() is that if there is a roof above the model will get teleported ontop of it.

1 Like

Just the new Pivot API that replaced the PrimaryPartCFrame API

To move it just use

your model:PivotTo(your cframe)

It will move the center of the model to the specified CFrame, or if you do have a primary part it will move that there and keep the other parts relative positions. Here’s more info about the Pivot API

1 Like

Do you know the size of the model? If you know the size, you will know exactly the position where it can be :MoveTo() so that it will spawn under that roof and just sit on the floor. Since model doesn’t have a size, you can estimate the part’s total height; or you can just use a temporary Part and scale it to cover the whole model then use the height axis (normally Y) then delete that temporary Part:

local floorY = theFloor.Size.Y/2
local modelY = 1.5 -- if the height of model is 3, half of that is 1.5
local Yposition = floorY + modelY
Model:MoveTo(theFloor.Position + Vector3.new(0,Yposition,0))

I just found out something about getting the Size of a model. It’s GetExtentsSize().

local floorY = theFloor.Size.Y/2
local modelY = Model:GetExtentsSize().Y/2
local Yposition = floorY + modelY
Model:MoveTo(theFloor.Position + Vector3.new(0,Yposition,0))

Use PivotTo, works like Model:PivotTo(Cframe.new( add position here )), i would probably have structured this better but im on mobile right now

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