Does anyone know how to make my freecam script rotate with right mouse button?

I want to make my own freecam script, similar to the one in Roblox Studio, and so far I made every part (ASDW movement + mouse wheel movement), except for rotation. I want to make it so when you hold right mouse button your camera rotates just like in Studio camera. I have some knowledge of cframes but my problem is that I dont know how exactly to measure when a player moves the mouse with right mouse button held and how to convert that into camera cframe rotation.

Heres my current code:

		local function getSpeed()
			if uis:IsKeyDown('LeftShift') or uis:IsKeyDown('RightShift') then
				return 0.25
			else
				return 1
			end
		end	

		r:BindToRenderStep("Freecam", 300, function()
			local speedFactor = getSpeed()
			
			-- forward/backwards
			if uis:IsKeyDown('W') then
				camera.CFrame += camera.CFrame.LookVector * speedFactor	
			elseif uis:IsKeyDown('S') then
				camera.CFrame -= camera.CFrame.LookVector * speedFactor
			end

			-- left/right
			if uis:IsKeyDown('A') then
				camera.CFrame -= camera.CFrame.RightVector * speedFactor
			elseif uis:IsKeyDown('D') then
				camera.CFrame += camera.CFrame.RightVector * speedFactor
			end	

			-- up/down
			if uis:IsKeyDown('E') then
				camera.CFrame += camera.CFrame.UpVector * speedFactor
			elseif uis:IsKeyDown('Q') then
				camera.CFrame -= camera.CFrame.UpVector * speedFactor
			end
		end)

So far I’ve tried using UserInputService.InputChanged to detect when a player moves the mouse around but as I said I dont know how to convert that into cframe rotation:

uis.InputChanged:Connect(function(input, isGameProcessed)
			if not isGameProcessed then
				if input.UserInputType == Enum.UserInputType.MouseMovement then					
					if uis:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) then
						local pos = input.Position
						print('input changed with RMB held:', pos.X,pos.Y)
						-- ...how do i convert to cframe rotation?
					end
                end
            end
end)

I didnt found any info on the web. Thanks for any help.

1 Like

You would rotate with the mouse delta.

Found this post which details it but has issues but I had solved it in this previous post.

local Delta = UIS:GetMouseDelta()
--adjust the delta X,Y haven't tested it out.
local NewCF = CFrame.fromOrientation(math.rad(Delta.Y),math.rad(Delta.X),0)--Rightclick drag CF
Cam.CFrame = Cam.CFrame*NewCF
2 Likes

Ok thanks, i will check it out now.

Okay so that method works perfectly:

-- inside renderstep loop

-- converting mouse delta values properly
local mouseDelta = uis:GetMouseDelta()
local SLOWNESS = 200
local x, y = -mouseDelta.X/SLOWNESS, -mouseDelta.Y/SLOWNESS

-- <some code here that implements ASDWEQ buttons camera movement>

-- right mouse button camera rotation
camera.CFrame *= CFrame.Angles(y,x,0) 

…but for some reason it also rotates the camera along the Z axis - that (intuitively) isnt supposed to happen because we have 0 as Z argument to CFrame.Angles. Do you have any idea on how to fix it?

The issue with CFrame.Angles first is that it applies in the following order:

CFrame.fromEulerAnglesXYZ ( number rx, number ry, number rz )

Creates a rotated CFrame using angles (rx, ry, rz) in radians. Rotations are applied in Z, Y, X order.

So it rotates the y axis first, then the X axis however because of the first Y axis rotation the subsequent X axis rotation becomes a Z axis roll kinda hard to visualize it.

Which is why CFrame.from Orientation is used.

--Recommend from orientation
camera.CFrame *= CFrame.fromOrientation(y,x,0) 

I tried using CFrame.fromOrientation() already as suggested in your other post and the effect still persists so I suppose the problem isnt in order of applying rotation to different axes. My best guess right now is that I need to somehow apply rotation to different axes distinctly. One of my friends suggested me to use that fancy axis angle thing but I kind of didnt get his idea.