Yes, if you use it on a model too many times, it will gradually start offsetting parts inside from their original offset because of floating point errors:
I can make hollow fuselages easier now
thanks!
This is intended for better performance (Firing Position / Orientation changes on everything has a noticable cost when a complex model is being moved). If you want to listen for a part moving thanks to PivotTo
(or BulkMoveTo
) you have to listen for CFrame
changes instead.
We’re very unlikely to change this. The intent is that handle summoning covers the use cases where having the handles at the edges was previously useful. Have you tried handle summoning, and if you have what scenarios are you still having trouble with?
Will the Touched event work for the Pivot points? I heard that Touched events don’t work in CFrames (I could be wrong about this).
I’ve tried that before and it worked, but it slows my building speed a little bit.
Just the fact that I have to select the center of a part to move it using the handles.
I’ll continue using the Studio Build Suite pivoting feature because it works better for my workflow.
So it’s that the handles get in the way of you clicking on the part to freeform drag it too much?
Sorry, I said the wrong word. Instead of dragging, I meant to say move using the handles.
Love it already!, this will be such a great addition to Developers!
Ty Roblox Staff
PivotTo
wont trigger touched events in the same way that other methods of moving stuff via script don’t trigger them. Parts only get touched events when they collide while moving thanks to physics simulation.
Ok, thank you. So, are there no way to have the Touched event triggered with scripts?
Not right now. The simulation team is actually going to look at exactly that issue some time reasonably soon, though what form the solution takes will depend what they turn up when they dig into the problem.
If you need a workaround you can call :GetTouchingParts()
on the moved parts to see if there’s anything touching them at the new location.
Thank you, I will have to try :GetTouchingParts()
later.
This function only works on parts that have CanCollide on.
Ok thank you for clarifying. I think it should be added to the documentation that you can instead listen to CFrame. If only I knew that in time…
It is actually documented, though the DevHub is having issues indexing the new documentation right now, so it’s a bit hard to find the page, someone is looking into the issue:
This is really cool and useful, thanks for adding this!
Should I still use Model.MoveTo if I want the model to be moved up until it doesn’t overlap any parts/terrain, or would it be better to implement this behavior myself with Model.PivotTo?
You could move over to Model:PivotTo
for that, but we’re not going to be deprecating Model:MoveTo()
at the same time as Model:SetPrimaryPartCFrame()
for exactly the reasons that you’re thinking of: It can still have useful behavior in some circumstances that’s not easy to replicate with other APIs (it’s possible, for instance the Collision based dragging in Studio is implemented with the normal Lua APIs, but it takes a lot of work to pull off).
It might eventually get deprecated at some point when we have shape-casts or something like that that would allow you to easily place an object on a surface, but currently Model:MoveTo()
still has some good uses.
1 odd thing I discovered while benchmarking SetPrimaryPartCFrame vs PivotTo is that PivotTo performs significantly slower when it get sets to the same CFrame over and over. When this is not the case, PivotTo obliterates SetPrimaryPartCFrame.
Same CFrame
Code
local ModelCFrame = CFrame.new(2, 5, 0)
function PivotTo(Model, PivotCFrame)
Model:PivotTo(PivotCFrame)
end
function SetPrimaryPart(Model, PrimaryPartCFrame)
Model:SetPrimaryPartCFrame(PrimaryPartCFrame)
end
wait(10)
local GamerModel = workspace.Trampoline
local StartTime = os.clock()
for i = 1, 10000 do
local NewVector3 = Vector3.new(2)
PivotTo(GamerModel, ModelCFrame + NewVector3)
end
local EndTime = os.clock() - StartTime
print("Pivot To: ".. EndTime)
local StartTime = os.clock()
for i = 1, 10000 do
local NewVector3 = Vector3.new(2)
SetPrimaryPart(GamerModel, ModelCFrame + NewVector3)
end
local EndTime = os.clock() - StartTime
print("SetPrimaryPart: ".. EndTime)
Different CFrame:
Code
local ModelCFrame = CFrame.new(2, 5, 0)
function PivotTo(Model, PivotCFrame)
Model:PivotTo(PivotCFrame)
end
function SetPrimaryPart(Model, PrimaryPartCFrame)
Model:SetPrimaryPartCFrame(PrimaryPartCFrame)
end
wait(10)
local GamerModel = workspace.Trampoline
local StartTime = os.clock()
for i = 1, 10000 do
local NewVector3 = Vector3.new(i % 2)
PivotTo(GamerModel, ModelCFrame + NewVector3)
end
local EndTime = os.clock() - StartTime
print("Pivot To: ".. EndTime)
local StartTime = os.clock()
for i = 1, 10000 do
local NewVector3 = Vector3.new(i % 2)
SetPrimaryPart(GamerModel, ModelCFrame + NewVector3)
end
local EndTime = os.clock() - StartTime
print("SetPrimaryPart: ".. EndTime)
Obviously, you shouldn’t be setting a model to the CFrame over and over again.