In Studio, it is currently possible to scale objects via the Scale tool, however doing so in-game or in community plugins is not as convenient. That changes today! We are excited to introduce a Scale Factor for Models beta feature which adds the following scaling APIs on Model:
Returns the current scale factor of the Model, which starts at 1 for existing and newly created Models. This scale factor is a property of the model which persists.
Sets the scale factor of the Model and updates the values of all scalable properties of descendants of the Model accordingly. All properties which have some geometric interpretation in the scene are scalable, including sizes, forces, speeds, etc. The scaling happens around the pivot.
The beta feature then integrates these APIs into Studio and the engine in three key ways:
Scaling in Studio “just works” on all types of content.
The package system supports scaling of packages
The animation system supports scaled playback of animations
Enabling the "Scale Factor for Models" beta
In the File menu select Beta Features and toggle on Scale Factor for Models in the Beta Features dialog. You will have to restart Studio for the change to apply.
There’s a lot to unpack here, so let’s go through the changes one by one.
1) The Scale tool “just works”
The Scale tool in Studio will now call
ScaleTo when scaling models. Since
ScaleTo scales many things and not just part sizes, you can now expect the Scale tool to scale a much wider array of Instance types under the models you scale rather than just changing the sizes of parts. This includes scaling:
- Visual effects like ParticleEmitters and Beams
- The rolloff distance of Sounds
- Forces and Torques in constraints
- Humanoid settings under character rigs
Overall, you can expect the Scale tool to do a much better job of scaling models out of the box.
2) Precise scaling in the Properties pane
It’s not just the scale tool getting in on the action! The properties pane now includes a numeric “Scale” property on Models, allowing you to precisely set exactly the scale you want. Want something to be exactly twice as big? Just type “2” in for the scale and watch the magic happen:
Please note that this isn’t a scriptable property.
ScaleTo should be used in scripts.
3) Packages support scale
Now that scale is an engine level API, the package system can tap into that API and support scaling. With this update, packages will no longer count as modified when scaled - as long as they have a Model as the root or consist of exactly one Part.
4) Animation scaling
Ever created several copies of the same animation to support different rig sizes, especially with R6? That’s something you’ll never have to do again.
The Animator Instance will key into the scale API to support scaled playback of animations!
Specifically, the Animator instance will scale any joint offsets in an animation by the scale factor of the Model the rig is rooted under. That means you’ll be able to dynamically scale a rig by calling
:ScaleTo in-game and have your animations work properly on that scaled rig.
5) Straighforward scaling in-game
Last but not least, dynamic object placement in-game or in plugins became a lot more simple with this update. The majority of dynamic object placement code can now be as simple as:
local object = prototype:Clone() object:PivotTo(targetLocation) object:ScaleTo(targetScale) object.Parent = ...
This will work regardless of how complex your object is. It could be as simple as a piece of static geometry, a vehicle full of joints and constraints, or even a full character rig wearing tools and accessories.
Scripting with Scale in mind
The scale API won’t be able to handle everything, in particular, the scale API can’t automatically change the behavior of scripts in your models - unless you keep scale in mind when scripting new models.
Scripts in models can read the scale factor of the model via
:GetScale(), and take it into account allowing those models to keep functioning perfectly without manual reconfiguration of scripts when scaled. We recommend trying out this approach with scripted content you intend to reuse or publish to the marketplace in the future.
As an example, here’s an updated copy of a car model we published in the past which now uses
:GetScale() to support scaling of scripted interactions (the magic happens in the
Chassis ModuleScript under the Scripts folder): BlueSportsCar.rbxm (350.3 KB)
This is a complex change with lots of moving parts, so we’re expecting a lot of developer feedback on it. We’d like to call out a few specific cases we were unsure of.
Texture / SurfaceGui scaling
SurfaceGuis have two obvious scaling approaches. They can be left alone, tiling additional times like a material as the surface scales, but they could also have their tiling parameters scaled such that they stretch like a Decal. We chose to scale them such that they stretch like a Decal, but this was a very close decision so we’d like to know if you think the other approach is better.
Scaling interactive elements
There are many interactive elements to scale such as
ProximityPrompts. We chose to scale the
MaxActivationDistance and similar properties on these but this was also a close decision. Let us know if scaling these cause any issues.
Scale tool understandability
The scale tool now acts differently depending on whether you’re scaling a Model or a single part. Previously the behavior in these two cases was almost identical. Now, scaling a Model will scale all of the descendants such as
Sounds, but those descendants will not be scaled when resizing a single part. We would love to hear from you if you think this split will cause you confusion when building.
Can I use this in live experiences yet?
ScaleTo API can only be called if the beta is enabled, but publishing content/packages you built using the enhanced scale tool will not cause any issues.
Animation scaling on the other hand works in live experiences immediately! Though for now, you will only be able to make use of it on character rigs you’ve scaled ahead of time in Studio.
Can I use this in Team Create during the beta?
Yes, but be careful with packages. If someone without the beta turned on tries to update a scaled package you may get unexpected results. In addition, if we adjust the scaling behavior in response to developer feedback you may see packages change slightly when you update them.
What about non-uniform scale?
A nonuniform scale is not feasible at this time for a number of reasons. In particular, handling the skew/shear of rotated children is problematic. This change doesn’t preclude us from eventually having nonuniform scale but if we do it will be quite a ways down the road.
How do you scale constraints?
You’re correct to recognize that there’s no “correct” way to scale constraints. As our core rule, we chose to preserve the critical damping of mechanisms as you scale a model. In simpler words, if your car’s suspension is “stable” (not overly springy or stiff) you can expect it to remain that way. For example, this means scaling a model up by 2x scales forces, and torques in that model up by 8x rather than just 2x.
These issues are currently being looked at:
PivotToon models with a Scale other than 1 on production will cause issues.
Humanoid walking is “slippery” when a humanoid is scaled down significantly.
Rojo has not been updated to handle scale correctly yet, so when building a rojo project file that includes both old models without scales and new models with scales, the old models will be treated as though they have a scale of 0 and cause issues. The Uplift fork of Rojo has been updated with a fix for this issue.
Following in the footsteps of model pivots, package system updates, etc, this feature marks the conclusion (for now ) of a long arc of engine changes making Models into the robust 3d content container they were always meant to be.
A big thanks to everyone involved:
- Me, for the main implementation
- The simulation team for figuring out how to scale physical properties consistently.
- The animation team for including animation scaling.
- The packages team for package system integrations.
- The alpha strike team for stress testing the various scaling behaviors.
- And many more! This feature had involvement from almost every engine team!