Making a parts CFrame along only one rotational axis

I’m trying to make a lever that a player must click and drag up/down to move it into the on/off position. Sortof like how you’d see in VR games. What I’d like to do is have the part rotate to face the mouse position using only CFrames, and then once it reaches a certain point disengage and be ‘on’. I got it to work using some distance magnitude trickery but it stutters, so I believe being able to have it face directly at the mouse position would fix the problem. However, I only want it to do so on the axis the lever moves on.

I found a previous post that solved my problem somewhat (it only moves on 1 axis), but I can’t figure out how to change it to the correct axis. As of now the lever moves side to side instead of up/down.

TL;DR: I need help on how to make this code rotate a lever up/down instead of side to side as the mouse moves.

Here is the code I’m using:

local forwardTemp = (mouse.Hit.p - mainmodel.PrimaryPart.Position).Unit -- edit: forgot .Unit
local up = mainmodel.PrimaryPart.CFrame.UpVector
local right = forwardTemp:Cross(up)
mainmodel:SetPrimaryPartCFrame(CFrame.fromMatrix(mainmodel.PrimaryPart.Position, right, up))

Thank you in advance for any assistance.

1 Like

If you want to make a lever with an axis of rotation, you can use:

CFrame.fromAxisAngle ( Vector3 v, number r )
Creates a rotated CFrame from a Unit Vector3 and a rotation in radians

To obtain the desired rotation along an axis. To which you can use CFrame math to make the lever rotate along it’s primary part.

1 Like

Perhaps its my own ignorance but that did not help solve the problem. The lever simply flipped out in all directions.

To reiterate–the code I have works, I just need to figure out how to switch the axis which it is controlling.

Instead of using the UpVector, try using the RightVector or LookVector

Which axis do you want the lever to rotate around? Which face of the lever is the “skinny” one?

Tried that–it resulted in the lever spinning around wildly.

I believe it would be the x axis.

Not sure what you mean by the second question.

Do you want to operate the lever like a hinge like this mech leg below?

https://streamable.com/4g39ly

If so then I would recommend using Motor6Ds and the CFrame.fromAxisAngle to rotate the lever.

I tried experimenting w/ that to no avail.

Perhaps I need to restate my question: All I am trying to figure out is how to SWAP the code above so that instead of rotating along the Y axis it rotates along the X axis. The above code works GREAT! It’s just rotating along the wrong axis.

Oh I see what you mean now, to stop it rotating side to side just set the right vector to a constant value.

I’m afraid that didn’t fix the problem–that only caused it to not move at all.

As it stands now it ONLY moves side to side. I would like to swap it so that it only move up/down.

Hope that makes sense.

Hmm if it only moves side to side then maybe make the up vector a constant value,

Hard to tell which way your model is oriented relative to the primary part without diagrams or picture or videos though.

so make the up vector constant

mainmodel:SetPrimaryPartCFrame(CFrame.fromMatrix(mainmodel.PrimaryPart.Position,right, mainmodel.PrimaryPart.CFrame.UpVector))

Cant you just use the original code and rotate it 90 degrees so its going up and down?

You should check out the first section of this page to understand what is going on in this code.

I mean, a lever looks like this:

|   |
|   |
|   V
|  ___
| /  /
|/  /
|  /
| /
|/
|
| 

You’ve said the X-axis is “coming out of the page”, so to speak. But, is that skinny face I’m pointing to the Top surface of the lever? Or is it the Front face?

Like if the lever was just at 0,0,0 orientation, is it tall and skinny or long and short?

Ed that is exactly what I want to do, but I’m not sure how to do it! If know how to rotate CFrames (Cframe.angle) but from what I can gather I’m dealing with Vector3’s here, and I do not know how to do the math to rotate a Vector3.

I’ll read through that page. The face you are pointing to is the Front face.

I started writing something about how to adapt this code, but I realized that it’s probably not what you want anyways.

If it is a VR game, the problem is easy, because you could point the lever towards the hand.

Imagine what it would mean for the lever to point directly at the mouse, though (constrained to the X-axis).

The mouse would probably be on the wall, so the lever would try to point to it… which means it would almost always be completely flush to the wall.

Instead, you’ll need a way to change the Y-position of the mouse into an angle. I would personally do this with the 2D position of the mouse, so that you don’t need to deal with weird depth issues.

Basically I would do something like this:

  1. Keep track of the lever’s angle in some variable angle.
  2. When the player clicks the lever, keep track of what the angle is currently in some variable startAngle, as well as the Y-position of the 2D mouse startMouseY
  3. While the player is holding the mouse button down, set angle = startAngle + (MOUSE.Y - startMouseY).
  4. Constantly set the lever’s CFrame to ROOT_CFRAME * CFrame.Angles(angle, 0, 0), where ROOT_CFRAME could just be the position of the lever’s mount point.
1 Like

Wow. I had thought of doing that at first but was worried that varying view sizes of players screens would cause it to not move properly. I was wrong. Thank you so much for that suggestion–wish I’d tried it 2 days ago…

1 Like