Tweening bricks to a computed shape

Essentially what I wish to do is to take a clump of bricks and move them into a shape. I wish to tween them between a resting position into a randomized shape (such as a sphere, or a duck, etc).

Here are some examples:
https://www.roblox.com/games/1994932/Satellite
https://www.roblox.com/games/1995049/Duck

I know how to get and manipulate bricks with tweens, but mathematically how would I go about computing such shapes?

If you have a pre-defined set of bricks to manipulate, you can move the bricks into the shape you want in Studio, save their CFrames in a table, and just set/tween the CFrames of the bricks to them again when needed.
If each brick is identical, you can save each brick in an array and use a for loop:

-- storing cframes
local Duck = {CFrame, CFrame, CFrame, ...}

-- deploying parts
for _, cf in pairs(Duck) do
    part = Part:Clone()
    part.CFrame = cf
    part.Parent = workspace
end

-- moving parts
for i, part in pairs(Clump:GetChildren())
    local cf = Duck[i]
    TweenService:Create(
        part,
        TweenInfo.new(),
        {CFrame = cf}
    ):Play()
end

if they are not, you would need to create a dictionary as a way of telling the difference between bricks.

-- storing
local Duck = {
    Part1 = {CFrame, CFrame, ...},
    Part2 = {...},
    ...
}

-- deploying
for partName, t in pairs(Duck) do
    local Part = ServerStorage[partName]
    for _, cf in pairs(t) do
        local part = Part:Clone()
        ...
    end
end

-- moving
local i = {}
for partName in pairs(Duck) do
    i[partName] = 0
end
for _, part in pairs(Clump:GetChildren()) do
    local partNum = i[part.Name]
    i[part.Name] = partNum + 1
    TweenService:Create(
        part,
        TweenInfo.new(),
        {CFrame = Duck[part.Name][partNum]}
    ):Play()
end

If you want to save extra variables, like brick colors, you can pair the CFrame and the color value together in a table, same with anything else you would want to change, like size, shape, or mesh id.

-- storing
local Duck = {
    {CFrame = CFrame, Color = Color3, ...},
    {...},
    ...
}

-- deploying
for _, t in pairs(Duck) do
    local part = Part:Clone()
    part.Color = t.Color
    part.CFrame = t.CFrame
    ...
end

-- moving
for i, part in pairs(Clump:GetChildren()) do
    local t = Duck[i]
    TweenService:Create(
        part,
        TweenInfo.new(),
        t,
    ):Play()
end

I would suggest building the model and then stealing values through some kind of instance serializer like this one, that way you wouldn’t have to go through the work of saving values by printing CFrame components or copying from the properties window:

After that, you can just copy the generated values to a table structure like above, and use smart for loops.

1 Like

First off, thank you for such a detailed answer about how to best tween the bricks together.

However, I’m still lost with how I could generate a shape such as a duck. How did clockwork create that duck shape? He definitely didn’t make it by hand.

1 Like

My first guess is that he looked at the mesh’s hard-coded polygons through Roblox’s mesh formatting, like if you opened a mesh file with something a bit more complex than Notepad, and created parts based off of the normal and position generated from each triangle. There was an article about how to read Roblox’s mesh format here:

My other guess is that he casted a lot of rays onto a mesh, and using their normals and positions returned, created a part at the ray’s point of contact. If this were the case though, he would have probably not been able to resize parts so that the copied mesh actually looked somewhat correct. There would be a lot of identical parts that would be under/oversized.

1 Like

Thanks again for all the thorough answers. I’ll see what I can do with this new information!

1 Like

Back in the day, Roblox’s mesh format was just a list of points in 3D space. As a result, you can could just create triangles or parts between those points and make the mesh (this was Version 1.0 and 1.1 of the mesh format). That’s likely what Clockwork did.

I actually have a (very large) heart mesh here that I did that to. Note that it’s a bit old so navigation might be an issue, but you can get the idea:

https://www.roblox.com/games/129083231/Heart

2 Likes