user2255700
user2255700

Reputation: 113

How to rotate a Roblox model?

I am working on a game which allows some buildings to be placed and procedurally rotated.

I found the following rotation code which I am trying to incorporate:

function TransformModel(objects, center, new, recurse)
    for _,object in pairs(objects) do
        if object:IsA("BasePart") then
            object.CFrame =     new:toWorldSpace(center:toObjectSpace(object.CFrame))
        end
        if recurse then
            TransformModel(object:GetChildren(), center, new, true)
        end
    end
end

Which is invoked as follows in my building placement script:

local center = model:GetModelCFrame()
TransformModel( model:GetChildren(), center, center * CFrame.Angles(0,math.rad(45),0), true )

The code works to some extent. The model does rotate, but it first jumps into the air and lands haphazardly before finally settling into the rotated position. However, the final rotation is far from an exact 45 degrees due to the physics effect of jumping and settling back down.

I am not quite sure but I suspect there is a better way to accomplish this where the model smoothly rotates. Any help would be greatly appreciated.

Thanks, Andy

Upvotes: 1

Views: 9393

Answers (3)

Advait_Nair
Advait_Nair

Reputation: 41

Now, GetPrimaryPartCFrame and SetPrimaryPartCFrame are not recommended for future projects. Instead, it is best to use SetPivot() and GetPivot().

(I understand that this topic was quite a while back ago, so I'm saying this to people who stumble upon this)

Upvotes: 1

UristMcSparks
UristMcSparks

Reputation: 161

GetModelCFrame is a deprecated method. It is instead recommended to utilize the PrimaryPart, GetPrimaryPartCFrame, and SetPrimaryPartCFrame. Setting the primary part designates a specific part in the model to serve as a base that you can move around via its CFrame. What's nice about this approach is that if you transform the PrimaryPart of a Model with these methods, all of the other parts in the Model will also transform to maintain their offset from the PrimaryPart.

For placing buildings and props, it is usually desired to have this part be a flat part at the bottom that represents the footprint of the building.

For example, consider the following model:

ROBLOX Model with a PrimaryPart

In this case the best part to make the primary part would be the one on the bottom. If your model doesn't have a part incorporated in the geometry then you can make an invisible and cancollide false part to serve as the base. In the following example, there is a tree model that doesn't have a wide base, but we want to make sure the footprint is large enough that it wouldn't overlap with other nearby objects:

ROBLOX Model with a translucent PrimaryPart

In this case the yellow part should be made fully transparent at runtime.

So in terms of the code to actually orient a model in the way you want, all you have to do is call SetPrimaryPartCFrame with the new CFrame. The TransformModel function simply becomes:

local function TransformModel(model, newCFrame)
    model:SetPrimaryPartCFrame(newCFrame)
end 

When you want to call this function to say rotate a model 45 degrees:

local model = game.Workspace.Model
model.PrimaryPart = model.Base
local rotatedCFrame = model:GetPrimaryPartCFrame() * CFrame.Angles(0, math.rad(45), 0)

TransformModel(model, rotatedCFrame)

Upvotes: 6

user2255700
user2255700

Reputation: 113

I believe I found an answer that works for my problem, though I am not sure if this is the best way to fix it. I created an extra part to act as a base which is the exact width and height of the model, the model then sits on top of the new base part and the base is anchored. That seems to have fixed it - is there a better way?

Upvotes: 1

Related Questions