How to rotate a Model

im trying to rotate a model with 2 parts as children using cframe, and this is what ive tried so far:

local script:

game.ReplicatedStorage.partevent:FireServer(position, rotation)

server script:

game.ReplicatedStorage.partevent.OnServerEvent:Connect(function(plr, position, rotation)

workspace.Model:SetPrimaryPartCFrame(position, rotation)

end

and this is what i get in the output: Unable to cast Vector3 to CoordinateFrame

i only got this error when i added the rotation, and im using CFrame.Angles(0, math.rad(90), 0) to set the rotation in advance.

(keep in mind this is just a small example of my script and may not be accurate)

2 Likes

Make sure the primarypart has been set inside of the model

Code: (if you’re trying to add position and rotation rather than set)

workspace.Model:PivotTo((workspace.Model.PrimaryPart.CFrame + position) * rotation)
3 Likes

You can either do what madmonty_lead says, or you can resolve the thing you did wrong

“workspace.Model:SetPrimaryPartCFrame(position, rotation)” does not give a CFrame you’ll have to change it to:

workspace.Model:SetPrimaryPartCFrame(CFrame.new(position, rotation))

Please feel free to ask if you have any further questions, sincerely,
oski3d1

2 Likes

I tried using your idea, but i got the error: ServerScriptService.placeBlock:62: invalid argument #1 to 'new' (Vector3 expected, got CFrame)

Just to clear things up, i am trying to set the cframe of a model to the mouse.Target which is using cframe for position and rotation.

anyways thanks for the help so far!

Whilst not a full solution to the problem, I’d suggest changing from :SetPrimaryPartCFrame() to :PivotTo(), as roblox has deprecated it.

hmm weird

I also belive you should use :PivotTo()
this uses a cframe inside the “( )” so keep in mind that you do not provide two values and just a singular CFrame value

Feel free to ask if this sounds confusing

1 Like

Okay, if I can only set the CFrame, how do I set the rotation o the model? Is there some kind of function that can rotate it?

rotation in your example is a CFrame. SetPrimaryPartCFrame() and PivotTo() take only one CFrame as an argument. That means you cannot provide position and rotation separately.

Best solution would be to costruct a CFrame on client, and provide it as a single remote event argument, ie:

game.ReplicatedStorage.partevent:FireServer(targetCFrame)

How to construct such CFrame will depend on what you want to achieve. I am going to assume you want to rotate the part on it’s Y axis. In this case, you can simply multiply it by CFrame.Angles:

local targetCFrame = model.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(90),0)

Hope this helps.

1 Like

Whenever im using CFrame.Angles() i always get the error invalid argument #2 (Vector3 expected, got CFrame).

What does this mean and how do i fix it?

There is no need to provide second (argument #2) at all. Neither PivotTo() nor SetPrimaryPartCFrame() require second argument.

All they need is a CFrame.

To clear up confusion, CFrame “includes” both position and rotation. You have not provided the code that errors, but I assume it is something like this:

--bad code example
part.CFrame = CFrame.new(part.Position,CFrame.Angles(0,0,math.rad(90)))

Many people make this mistake. This code will error, as the second argument to the CFrame.new() constuctor has to be a Vector3, in this case, a point in space where the front face of a part should face. This particular constructor has been replaced by CFrame.LookAt(), but I digress.

What you really need is to apply rotation to the model, without changing its position. To rotate a part on its axis, without changing its position, multiply part’s CFrame by CFrame.Angles():

model:PivotTo(model:GetPivot() * CFrame.Angles(0,0,math.rad(90)))

If you want to rotate the part on the world axis use:

model:PivotTo((CFrame.Angles(0, 0, math.rad(90)) * (model:GetPivot() - model:GetPivot().Position) + model:GetPivot().Position)

So your final code should look something like this (for the rotation on model’s axis)

--local script
local newCFrame = workspace.Model:GetPivot() * CFrame.Angles(0,0,math.rad(90))
game.ReplicatedStorage.partevent:FireServer(newCFrame)

--server script
game.ReplicatedStorage.partevent.OnServerEvent:Connect(function(plr, newCFrame)

   workspace.Model:PivotTo(newCFrame)

end)
1 Like

Alright, I tried using the code as an example: and this is what happened:

In this video example, you can see that first I tried using only pos which stands for position and it worked.

But the second time, when I used pos * ori2 which stands for orientation, it got placed very far away.

I think this is happening because what I am doing, is multiplying the x, y, and z by the said orientation, not adding it.

I set the orientation to 30, 40, 20 just randomly to see if it would work, and I think its just multiplying the CFrame, so that the block gets positioned way off.

they do still get rotated perfectly though, but hey also get positioned way off.

How do I make it so that the orientation information is inside the correct CFrame, like you told me to?

(btw ignore the attempt to index nil with name ill fix it another time)

So first thing first. CFrame is essentially a Matrix. Multiplying matrices is not commutative. What that means is that
CFrame1 * CFrame2 is not the same as CFrame2 * CFrame1.

So it is very important to multiply position like this:

local pos = pos1 * ori2

local pos = ori2 * pos1 -- this is wrong.

Second of all, ori2 has to be a CFrame and cannot have a position on its own. Essentially this code:

print(ori2.Position)

has to print out:

0,0,0

CFrame.Angles() will create a CFrame for you that has a zero positional value. So if you take any model or part CFrame and multiply it by this, the model/part will remain in the same spot. There are other ways to rotate a CFrame, but for strict rotation, that takes into account previous rotation, multiplication method is the way to go.

Now for the ori2 variable. Creating this will depend on your needs. For example, to rotate model on its “Y” axis, you can create ori2 like this:

local ori2 = CFrame.Angles(0,math.rad(90),0)
1 Like

Thank you so much for helping me, this means alot! :smile:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.