Rotating a Part globally for placement system

Hello. I am making a placement system and I want the player to be able to rotate an object before placing it. Here is the code I have so far to make the object rotate globally (so the player won’t get confused when pressing R and the part isn’t spinning in the same direction as before).

I am having trouble making the part rotate globally because right now, The part might randomly flip in the wrong direction randomly.

I have looked at other forums and they all talk about rotating in only one direction, so I wasn’t able to get help.

Here is my code (and please use it in a baseplate or something to see a better understanding on what’s wrong)

You can set the variable ‘ro’ to a part in workspace

game:GetService("UserInputService").InputBegan:Connect(function(i)
	local delta
	local ro = game.ReplicatedStorage.RotatePart
	if i.KeyCode == Enum.KeyCode.R then
		delta = CFrame.Angles(0,1.5708,0)
	elseif i.KeyCode == Enum.KeyCode.T then
		delta = CFrame.Angles(1.5708,0,0)
	elseif i.KeyCode == Enum.KeyCode.Y then
		delta = CFrame.Angles(0,0,1.5708)
	end
	
	if delta then
		ro.CFrame = ((ro.CFrame-ro.Position)*delta)+ro.CFrame.Position
		rotate = ro.Orientation
	end
	
end)
1 Like

What do you mean by wrong direction?

local part = game.ReplicatedStorage.RotatePart
local rotation = math.rad(90)
game:GetService("UserInputService").InputBegan:Connect(function(i)
    local delta
	if i.KeyCode == Enum.KeyCode.R then
		delta = CFrame.Angles(0,rotation,0)
	elseif i.KeyCode == Enum.KeyCode.T then
		delta = CFrame.Angles(rotation,0,0)
	elseif i.KeyCode == Enum.KeyCode.Y then
		delta = CFrame.Angles(0,0,rotation)
	end
	
	if delta then
		part.CFrame *= delta
	end	
end)

It’s not clear what the issue is from your description so I’m guessing it’s that you want these rotations based on the world’s cframe so that any part will rotate in the same manner just based on the key that you press.

This line seems like the issue:

as the order of multiplying the cframes matters and determines the axis of rotation. I think changing it to

ro.CFrame = (delta*(ro.CFrame-ro.Position))+ro.CFrame.Position

may solve the problem.

When you create a new CFrame using e.g. CFrame.Angles, it’ll always be in world space. To rotate the part relative to it’s current orientation you must convert that CFrame to the part’s coordinate space.

One other thing, instead of hardcoding a (wrong) value for pi/2, it’s better to just use the built-in math.pi.

I think this should work:

game:GetService("UserInputService").InputBegan:Connect(function(i)
	local delta
	local ro = game.ReplicatedStorage.RotatePart
        
	if i.KeyCode == Enum.KeyCode.R then
		delta = CFrame.Angles(0, math.pi/2, 0)
	elseif i.KeyCode == Enum.KeyCode.T then
		delta = CFrame.Angles(math.pi/2, 0, 0)
	elseif i.KeyCode == Enum.KeyCode.Y then
		delta = CFrame.Angles(0, 0, math.pi/2)
	end
	
	if delta then
                delta = ro.CFrame:ToObjectSpace(delta)
		ro.CFrame *= delta --No need to subtract the position
		rotate = ro.Orientation
	end
end)

Thank you very much! This helped me out.

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