ModelMover is obsolete. Do not use it for new work.
It has been replaced by the native method PVInstance:PivotTo, which functions for both models and parts alike. For obvious reasons, this module is no longer supported.
Introduction to ModelMover
If you’ve made extensive use of Model:SetPrimaryPartCFrame
you are no stranger to the inherent inaccuracies it can acquire over time. For instance, if I rotate a model by getting it’s PrimaryPart’s CFrame, modifying that, and then setting it to the new value, you can very obviously see the parts drift as you repeat calls.
The solution to this problem is incredibly simple – Cache the original original CFrames (the ones from before the first call to move the model). That’s precisely what my module does.
When using my module, you start by calling GetCFrameTable
on a model. This will return a table whose keys are parts and values are their CFrames relative to PrimaryPart
. After that, you call SetPrimaryPartCFrame
via my module and pass in that table, and rather than grabbing the CFrames fresh every time, it uses the baked CFrames to retain accuracy.
Here’s an example of this in action. The top model uses my system, and the bottom model uses the stock SetPrimaryPartCFrame
method. The video was started after a mere two full rotations about the Y axis. The CFrame of the PrimaryParts of each model, top and bottom, are -2, 5, 25446
and -2, -3, 25446
respectively (this was done far away to purposely get high inaccuracy)
The Module
The module and an example (the thing in the video) can be found here: https://www.roblox.com/library/5476680460/ModelMover
API
table ModelMover.GetCFrameTable(Model model)
Returns a table where keys are the part descendants of the model, and values are their CFrames relative to the model’s PrimaryPart. Errors if the input value is not a model, or if it is a model but it does not have a PrimaryPart set.
void ModelMover.SetPrimaryPartCFrame(Model model, CFrame cframe, table originalCFrameTable)
Sets the CFrame of the model’s PrimaryPart to the given cframe
, using originalCFrameTable
to orient the parts inside around the PrimaryPart. This table should be acquired via the GetCFrameTable
function. Errors if the input model
is not a Model or if it is a model but does not have a PrimaryPart set, errors if cframe
is not a CFrame, and warns for every part that is in the model but not present in originalCFrameTable
. If originalCFrameTable
is nil, this will call Roblox’s default SetPrimaryPartCFrame
method automatically.
For implementation of this API, refer to the bundled example.