How could I go about making a free-moving part with rotation locked to one axis?

  1. What do you want to achieve? I am currently working on a game that will feature a system where players can pick up, carry and throw certain objects (which for the sake of this post I will refer to as “grabbables”). For many reasons, such as stylisation and ease of use in puzzles/platforming, I want to limit the rotation of these grabbables to one axis.

  2. What is the issue? I have been unable to find a way to limit the rotation of the grabbables despite my best efforts.

  3. What solutions have you tried so far?

  • Updating the part’s CFrame every frame to set its RX and RZ to 0. This works well except for when the object interacts with slopes, which this game will feature a lot of.
  • Using a combination of AlignOrientations to limit the rotation to one axis. This almost works perfectly but it has the added side effect of causing the freely rotating axis to always attempt to pivot towards a resting point.
  • Using a HingeConstraint. This locks the part’s position in place.

Do you need to make it with a script? If not necessary, try DragDetectors, they have a ton of modes you can select for dragging, and they have mobile support built-in.

If you need it with a script, please elaborate on the meaning of “one axis” do you want it not to rotate and always face a direction? Or only being able to move it on one axis?

Hey, you can try monitoring the object orientation using its CFrame and every heartbeat check the cframe for example lets make it X axis with a limit of 30 degress

degree = math.clamp(math.deg(x), -30, 30)

then we set a new angle

partname.CFrame = CFrame.Angles(math.rad(x), y, z)

this is how it would basically works

I can do it with scripts or constraints, I have an object loading system so lag shouldn’t be an issue really. What I mean by one axis is that I only want the object to rotate on the Y-axis of its rotation property. The other 2 axis should be locked to zero. I will check out drag detectors when I get the chance as that actually does sound a little promising for locking the rotation.

1 Like

Something like this can work:

local part = --Part Location
local angle = 45

part.CFrame = part.CFrame * CFrame.Angles(0, math.rad(angle), 0)

now you can implement this into your code, if you need help with that, let me know.