Pivot Editor: Full Release

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:

2 Likes

I can make hollow fuselages easier now :sunglasses:

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.

3 Likes

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?

3 Likes

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?

3 Likes

Sorry, I said the wrong word. Instead of dragging, I meant to say move using the handles.

1 Like

Love it already!, this will be such a great addition to Developers!
Ty Roblox Staff :smiley:

2 Likes

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.

1 Like

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.

2 Likes

Thank you, I will have to try :GetTouchingParts() later. :grinning:

1 Like

This function only works on parts that have CanCollide on.

1 Like

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:

2 Likes

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.

4 Likes

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
image

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:
image

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.