Introducing an Engine-Level Model Scale API [Beta]

Update 6/7/23: The feature is now live on production, enjoy!


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:

  • Model:GetScale()

    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.

  • Model:ScaleTo(scaleFactor)

    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.

image

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.

ResizeEffects

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. GetScale / 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.

image

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.

NopeDemo

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)


Feedback

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

Textures / 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 ClickDetectors and 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 ParticleEmitters and 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.


FAQ

Can I use this in live experiences yet?

The 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.


Known Issues

  • Attention Rojo users: Older versions of Rojo do not know how to handle the scale properly, incorrectly assuming it should be set to zero. The latest versions of both mainline Rojo and the Uplift fork have been updated to handle things correctly. If you run into any issues with Models disappearing when edited, or notice models with zero scale in your experience, make sure to update your Rojo installation.

Conclusion

Following in the footsteps of model pivots, package system updates, etc, this feature marks the conclusion (for now :thinking:) 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!

Update August 2023

  • Added a “Reset Scale” button which will reset the scale factor of the selected model(s) back to 1 without changing their size:
    image

Thank you.

375 Likes

This topic was automatically opened after 10 minutes.

Disappointed that this API gives us no extra possibility for anything all that useful with being limited to only one transform, but alas, thank you for the feature!

11 Likes

Good update! This is a great feature for viewmodels, since it allows first-person shooter developers to implement first-person weapons that don’t clip with the environment, all without sacrificing texture and animation quality.

18 Likes

I’m likely going to have a handful of followup questions a bit later, but for now:

What’s the difference between this, and animation retargeting? If memory serves correctly, Roblox was working on a feature (not sure if it’s released) that lets an animation look identical regardless of rig proportions (fat and wide, tall and skinny, etc).

4 Likes

LETS GOOOO!!!

I never thought the day would come, especiallly after an employee said that something like Animation:AdjustScale wouldnt be added. But here we are!

This is such a lifesaver.

Oh, and yeah easily scaling models is cool as well. Shame that we dont get a Vector3 instead, but the the limitation of skewing parts is fair enough.

6 Likes

Animation retargeting is a “best guess” system, to some degree it has to guess your intent. This on the other hand is a deterministic transform on the input data.

Both of them compose together favorably: If the retargeting system has better input data already including the scaled offsets to work with it can do a better job because it only has to worry about the difference in rig shape and not try to sort out both shape and size differences at the same time.

8 Likes

Roblox has recently been on a good streak of delivering updates I enjoy. I want to express how much I appreciate the work you folks have been doing so far and that it is definitely really exciting to see new updates again.

I’d also like to see further implementation of more potential additional scaling axis’ in the future for scaling models. Though I can understand the difficulty in doing so.

4 Likes

Cool stuff! I really like this feature, but I don’t agree with scaling non-physical or non-appearance things like MaxActivationDistance - if I have a light switch that’s half the size, I shouldn’t have to move a lot closer to click on the smaller one. I expect the Scale tool to only affect the size of the object, nothing else.

Stretching texture sizes seems alright to me, though. Thanks for the update!

7 Likes

Worth noting that this update in no way makes it harder for us to offer nonuniform scale some day… that day is just likely a long ways down the road because a lot of other engine capabilities would have to come together to make it possible.

12 Likes

Fun fact for those who don’t know, the Workspace has a scale property and it works. Sadly, things still can’t go about 2048 but it’s still REALLY useful.

8 Likes

I think the same thing when it comes to scaling certain things.

When I scale my player character, I dont want things like the overhead nametag billboardGui to scale with it. Have to adjust it manually after changing the model scale. Oh well

3 Likes

THIS SUPPORTS VFX???

I cant wait for this to release publicly, but I am curious, will it be possible to blacklist what cant be affected by the scaling function (sounds, particles, etc.) and will the lights be influenced as well and have a bigger max radius than 60 since this is releasing?

3 Likes

Does this work out of the box with player characters? Any caveats here?

2 Likes

Nope. It Just Works™ with characters.

Though keep in mind you’ll want to scale the character on the server or else you’ll end up with physics desync between client / server.

21 Likes

>:O
Legendary. Adding character scaling to my custom character game ASAP.

6 Likes

I was testing out the animation scaling, and I have a small issue.

If you make an animation for a rig thats a different scale (for instance, 2), it gets saved as if it was the default scale. Meaning that if you play the animation on the same rig it was saved on, it wont look right.

Am I doing something wrong here?

1 Like

Ah, I haven’t updated the AnimationClipEditor. So you should edit the animation on a rig with Scale of 1 or else things will go wrong. I’ll get that fixed.

6 Likes

This is hilarious, but I do notice that this breaks layered clothing on the client.
image
image

There’s also an offset on climbing trusses.
image

And last thing to note from a cursory look is that the forces involved in moving the character are not scaled, so you move around like you’re sliding on ice, or otherwise struggle (albeit this is an issue with really small character models too, so this value doesn’t seem to be recalculated based on mass).

16 Likes

Why is Scale a NotAccessible property here that needs a method to be used.

2 Likes