ModelAssembler - Gracefully construct models

Introduction

Greetings fellow developers, recently I was looking for a system to animate constructing models for use in a game I’m working on. I couldn’t find anything that met my needs, so I created this. Hopefully it helps someone else too!

What is ModelAssembler?

ModelAssembler uses TweenService to animate the parts in a model to “build” it. Models (or parts) are placed in a location such as ServerStorage, and ModelAssembler will construct it in workspace. Below is an example using a picnic bench.

I2VTh4wTN7


Usage

To use ModelAssembler, first grab the model below and insert it into your game, preferably in ServerScriptService.

Roblox Model

Once the module is in your game, require it from the script you wish to use it in.

local ModelAssembler = require(game:GetService("ServerScriptService").ModelAssembler)

To create a new ModelAssembler object, call the .new() method and pass the model that you wish to build. Make sure that your model has a primary part, you’ll receive an error if it doesn’t.

local assembler = ModelAssembler.new(model)

To create the building animation, use the :Build() method and supply both the CFrame where the model is going to be built and the speed in seconds it will take for the entire model to be built.

assembler:Build(CFrame.new(), 5)

Documentation:

-- Methods
ModelAssembler:BuildOnce(model, cframe, speed) -- Builds the model supplied once, cleans up afterwards
assembler = ModelAssembler.new(model) -- Creates a new ModelAssembler object
assembler:Build(cframe, speed) -- Builds the model previously attached, can be called multiple times
assembler:Destroy() -- Destroys the assembler

-- Properties
assembler.Model -- Model
assembler.InstanceAdded -- Signal
assembler.Completed -- Signal
assembler.FlyInFrom -- CFrame
assembler.StartingTransparency -- Number

Examples:

local ModelAssembler = require(game.ServerScriptService.ModelAssembler)

local assembler = ModelAssembler.new(game.ServerStorage.Bench)

assembler.InstanceAdded:Connect(function(inst)
	assembler.FlyInFrom = CFrame.new(Vector3.new(math.random(0, 5), math.random(0, 5), math.random(0, 5))) * CFrame.Angles(math.random(math.pi*2), math.random(math.pi*2), math.random(math.pi*2))
end)

assembler.Completed:Connect(function(model)
	print(model)
end)

assembler:Build(CFrame.new(Vector3.new(0, 10, 0)), 10)
ModelAssembler:BuildOnce(game.ServerStorage.Bench, CFrame.new(Vector3.new(10, 5, 0)) * CFrame.Angles(0, math.rad(90), 0), 10)

Conclusion

Thanks for reading! I hope this is beneficial to your game. Feel free to give suggestions, I plan to actively maintain this system and add new features.

Special thanks to @steven4547466 for helping convert my original code to OOP as well as adding some new features. The original module is below if you would like a simpler version or you’re not as advanced in programming.
ModelAssembler Original

60 Likes

This is cool, consider adding an event for when the model is done building (similar to how tweens have a completed event)

5 Likes

Thanks! Good idea, an event could definitely be used for notifying upon completion, I’ll consider adding a Signal or even a Promise. You could always wait() for the duration you set as the time, but I know wait has some controversy.

1 Like

I mainly bring it up because event driven programming is much better than delaying threads and using waits or utilizing coroutines.

1 Like

I completely agree with you, but in the interest of keeping it simple, I’m leaning away from adding dependencies.

1 Like

I don’t think it would require any dependencies to add. I’ll fork your repo because I have some ideas and possibly you can see what you think when I complete it? Perhaps because you want to keep it simple, it could be on a separate branch or module completely.

Edit: I just realized it’s only a gist actually lol my bad.

1 Like

Please do, I’d love to see your ideas.

1 Like

Wow Just tested this in my vending machine build it looks amazing?!?!

1 Like

Also quick bug. It doesnt clone surface guis.

1 Like

Thanks for letting me know, I’ll write a solution that will probably just clone all the non-baseparts after all the tweens are complete.

2 Likes

Also you should make it so it groups all parts. Since when it finishes its ungrouped

1 Like

Thanks for your observations, I’ve edited the code to:

  1. Actually clone the original instance (I realized I wasn’t doing this, oops)
  2. Put the parts in a model in workspace
  3. Clone any non-basepart children (guis, lights, particles, etc) once the animation on each basepart descendant completes
2 Likes

Nice Module,but i guess i found a bug/error where if the model had a part which had an attachment,the module gives an error

this happened when i try spawning a car with this module

2 Likes

wow this is really nice, great work!

2 Likes

Why would you bring up such small micro-optimizations here? OP has no reason to micro-optimize in the first place - assert is expensive relative to if then statements - on the absolute scale, assert is absolutely inexpensive.

1 Like

I’ve already read that post before. It’s TL;DR is to use assert “carefully” because “it can be expensive.” The whole point of that thread is to be mindful of when to use it - not to never use it in the first place. Pre-emptive optimization is useless; this resource has no faults with lag nor performance, hence you have absolutely no need to bring up an unneeded warning. As the saying goes, premature optimization is the root of all evil.

Feel free to prove me wrong, but then again you’ll also need to prove all of these resources wrong, too :slightly_smiling_face:
https://stackify.com/premature-optimization-evil/
http://wiki.c2.com/?PrematureOptimization
https://tanzu.vmware.com/content/blog/preemptive-optimization
https://ubiquity.acm.org/article.cfm?id=1513451
https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
https://ieeexplore.ieee.org/document/7153787
…and many more, these are just the first-page results from Google.

1 Like

This looks really really good! Might use something like this for my game!

1 Like

does not work with models with parts with attachments on to them and was kinda sad when it didn’t work with some models

This is so cool!
Even though its super specific it can be used for so many different purposes and just generally looks awesome.

I already have tons of ideas: tycoons, model assembly simulator games, a house building mechanic, and even more! It’s super awesome!

1 Like

Can this build a city? Asking so I don’t have to build one.

2 Likes