Trouble with camera movement

So I am trying to create something that locks the players mouse in the center of the screen and then when ever you move you’re mouse to the left or right the camera moves to the left to right.
Now uh yeah the camera does not turn at all, so how can I fix this?

-- services
local players = game:GetService('Players')
local UIS = game:GetService('UserInputService')

-- players
local player = players.LocalPlayer
local char = player.Character

if not char then
	player.CharacterAdded:Wait()
	char = player.Character
end
local Root = char.PrimaryPart

local Mouse = player:GetMouse()

-- camera
local camera = workspace.Camera

-- setup
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter


Mouse.Move:Connect(function()
	local CF = Root.CFrame * CFrame.new(0,3,0)
	local mouseDelta = UIS:GetMouseDelta()

	if mouseDelta.X > 0 then
		print("Right")
		CF *= CFrame.Angles(math.random(5),0,0)
	else
		print("Left")
		CF *= CFrame.Angles(-math.random(5),0,0)
	end

	if mouseDelta.Y < 0 then
		print("Up")
	else
		print("Down")
	end
	
	camera.CFrame = CF
end)

Ps if there is a better way to do this please tell me

1 Like

I would suggest creating a Sensitivity variable, to control how fast the camera moves.
Currently, the problem is that when you get the CF variable, you are rotating the camera with the player character.
Another issue, is that the camera only updates its position when Mouse.Move is called.

-- services
local players = game:GetService('Players')
local UIS = game:GetService('UserInputService')
local RS = game:GetService(' RunService ')

-- players
local player = players.LocalPlayer
local char = player.Character

if not char then
	player.CharacterAdded:Wait()
	char = player.Character
end
local Root = char.PrimaryPart

local Mouse = player:GetMouse()

-- camera
local camera = workspace.Camera

-- setup
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter


local CameraSensitivity = 0.5
local CameraPositionOffset = Vector3.new(0,3,0)
local CameraOffset = CFrame.new(0,0,0)

local CameraCFrame = CFrame.new(Root.Position) * CameraOffset
local CameraRotation = Vector2.new()

RS:BindToRenderStep(' CameraControl ', 305, function() --Calls every frame
	local mouseDelta = UIS:GetMouseDelta() * MouseSensitivity
-- Multiply the change by the sensitivity
	CameraCFrame = CFrame.new(Root.Position) * CFrame.new(CameraPositionOffset)
-- Offset the cameras position
	if mouseDelta.Magnitude > 1 then
	 	CameraRotation += mouseDelta
		CameraCFrame = CameraCFrame * CFrame.Angles(0,CameraRotation.X,0) * CFrame.Angles(CameraRotation.Y,0,0)
	-- This just rotates the camera by however much the mouse moved, but doesnt account for the resolution
	--If you want to do that, divide mouseDelta by camera.ViewPortSize.Y, then up the sensitivity a lot, don’t recommend doing this
	end

	camera.CFrame = CameraCFrame:ToWorldSpace(CameraOffset) --Extra offsets that use the cameras current rotation, then applies it to the camera
end)

Well to point it out it is meant to be based of the players characters position due to how Im making it, also what would you recommend setting the MouseSensitivity value too?

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart -- Assuming the character has a PrimaryPart, adjust if needed
local Mouse = player:GetMouse()
local camera = workspace.Camera -- Assuming there's a Camera object in the workspace

UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivity as needed
local CameraOffset = CFrame.new(0, 0, 5) -- Adjust the offset as needed

local function onMouseMove()
    local mouseDelta = UserInputService:GetMouseDelta() * CameraSensitivity

    if mouseDelta.Magnitude > 1 then
        -- Calculate new rotation based on mouse movement
        local newRotation = camera.CFrame * CFrame.Angles(0, math.rad(-mouseDelta.x), 0)
        
        -- Apply camera offset to the new rotation
        camera.CFrame = newRotation * CameraOffset
    end
end

-- Connect the function to the mouse movement event
UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        onMouseMove()
    end
end)

Awesome! This works!

PS if you dont mind explaining how it works that’d be nice.

How can I make it so this also allows you to look up and down?

--Camera Parameters:
local CameraSensitivity = 0.5: --Sets the sensitivity of the camera movement.
local CameraOffset = CFrame.new(0, 0, 5): --Defines a CFrame offset for the camera (adjust as needed).

--onMouseMove Function:
local function onMouseMove(): --Defines a function to handle mouse movement.
local mouseDelta = UserInputService:GetMouseDelta() * CameraSensitivity: --Gets the mouse movement and scales it by sensitivity.
if mouseDelta.Magnitude > 1 then: --Checks if the mouse movement is significant.
local newRotation = camera.CFrame * CFrame.Angles(0, math.rad(-mouseDelta.x), 0): --Calculates a new camera rotation based on horizontal mouse movement.
camera.CFrame = newRotation * CameraOffset: --Applies the calculated rotation with the predefined offset to the camera.

--Connect Function to Mouse Movement Event:
UserInputService.InputChanged:Connect(function(input, gameProcessedEvent): --Connects a function to the InputChanged event.
if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then: --Checks if the input is mouse movement and not processed by the game.
onMouseMove(): --Calls the onMouseMove function to handle camera movement.

To be able to move up and down as well you’d do

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart 
local Mouse = player:GetMouse()
local camera = workspace.Camera


UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivty as needed
local CameraOffset = CFrame.new(0, 0, 5) -- Adjust the offset as needed

local function onMouseMove()
    local mouseDelta = UserInputService:GetMouseDelta() * CameraSensitivity

    if mouseDelta.Magnitude > 1 then
        -- Calculate new rotation based on both horizontal and vertical mouse movement
        local newRotation = camera.CFrame * CFrame.Angles(math.rad(-mouseDelta.y), math.rad(-mouseDelta.x), 0)
        
        -- Apply camera offset to the new rotation
        camera.CFrame = newRotation * CameraOffset
    end
end

UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        onMouseMove()
    end
end)

I’ve changed the calculation of newRotation to include both horizontal and vertical mouse movement. The CFrame.Angles now takes both -mouseDelta.y for vertical movement and -mouseDelta.x for horizontal movement.

I hope I explained it well enough, if you don’t understand a specific part of it just let me know.

so this does some what work just not in the way I want.

I wish for it to kind of be like you’re in third person, as of now when you turn your mouse the cameras position gets moved, I just wish for the camera to turn and not its position to rotate, I also noticed that if you change the Y value of the offset it just kinda breaks

Try this

I changed the calculation of newRotation to use the character’s LookVector instead of the entire CFrame. This should make the camera turn without changing its position.
adjusted the updateCamera function to use the LookVector for creating the new rotation.


local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart
local Mouse = player:GetMouse()
local camera = workspace.Camera 

UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivity as needed
local CameraOffset = CFrame.new(0, 0, 5) -- Adjust the offset as needed

local function updateCamera()
    local characterRotation = Root.CFrame:PointToWorldSpace(Vector3.new(0, 0, 1))
    local newRotation = CFrame.new(Vector3.new(), characterRotation.LookVector)

    camera.CFrame = newRotation * CameraOffset
end

UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        updateCamera()
    end
end)

1 Like

From the look of it this isnt working, maybe its cause characterRotation isnt by default a CFrame and that changing it to one so I can get the lookvector is causing problems.
Other than that I really dont know.

1 Like

Ya I think you’re right.

This should extract the LookVector from Root.CFrame instead of converting characterRotation to a CFrame and then extracting the LookVector


local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart 
local Mouse = player:GetMouse()
local camera = workspace.Camera

UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivity as needed
local CameraOffset = CFrame.new(0, 0, 5) -- Adjust the offset as needed

local function updateCamera()
    local lookVector = Root.CFrame.LookVector
    local newRotation = CFrame.new(Vector3.new(), lookVector)

    camera.CFrame = newRotation * CameraOffset
end

UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        updateCamera()
    end
end)

    local lookVector = Root.CFrame.LookVector
    local newRotation = CFrame.new(Vector3.new(), lookVector)

This captures the forward direction of the character’s Root and use it to create a new CFrame that represents a rotation. This rotation is then used to set the camera’s orientation, allowing the camera to turn in the same direction the character is facing without changing its position.

same thing as before, not sure what I did but it aint working. No errors btw

hmmm

In this version, Root.CFrame is directly used to get the character’s rotation, and then CFrame.new(Vector3.new(), characterRotation.LookVector) creates a new CFrame with the same rotation. This might help.

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart 
local Mouse = player:GetMouse()
local camera = workspace.Camera
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivity as needed
local CameraOffset = CFrame.new(0, 0, 5) -- Adjust the offset as needed

local function updateCamera()
    local characterRotation = Root.CFrame
    local newRotation = CFrame.new(Vector3.new(), characterRotation.LookVector)

    camera.CFrame = newRotation * CameraOffset
end

UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        updateCamera()
    end
end)

If there is still an issue it might be something affecting such as:

Camera properties like FieldOfView or ViewportSize might influence its behavior.

Constraints like BodyGyro or BodyPosition might interfere with manual camera adjustments.

Any other script affecting camera would/could cause issues.

Hmm I still have no idea what I did. I got the whole script and stuff and it still just doesnt work.
At this point I dont know what to do

Can you explain what you mean by not working. Maybe I’m just not understanding how you want the camera exactly to act.

Ill show you a video


From this video you can just see a single part (which is the spawnpad btw)
Now you probably might also see a ball, that is the players character (Dont ask why its a ball)
And uh well no matter how much I move my mouse nothing happens.

After trying it without the custom character I can see that it does kinda move but I cant move it like over 30 ish degrees, Its also very jittery and after I move my mouse instantly snaps back to look in one direction.

So to say, I have no idea what to do at all.

Do all iterations I provided have the same outcome or do any work a little bit better than others?

The first one worked that you sent

Ok and my second reply added the Up and Down functional you said it works but not in the way you want due to:
“as of now when you turn your mouse the cameras position gets moved, I just wish for the camera to turn and not its position to rotate, I also noticed that if you change the Y value of the offset it just kinda breaks”

Ya changing the offset can break it. I think this version of the script can work but I think we just need to tune in the offset try and get the right values.

So what happens if you have an offset like in the code below? If nothing works after a few attempts could you send another video of trying it?

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Root = character.PrimaryPart
local Mouse = player:GetMouse()
local camera = workspace.Camera

UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

local CameraSensitivity = 0.5 -- Adjust the sensitivity as needed
local CameraOffset = CFrame.new(0, 2, -5) -- Adjust the offset as needed (example: Y offset of 2 units, Z offset of -5 units)

local function onMouseMove()
    local mouseDelta = UserInputService:GetMouseDelta() * CameraSensitivity

    if mouseDelta.Magnitude > 1 then
        -- Calculate new rotation based on both horizontal and vertical mouse movement
        local newRotation = camera.CFrame * CFrame.Angles(math.rad(-mouseDelta.y), math.rad(-mouseDelta.x), 0)

        -- Apply only the rotation to the camera with a small offset
        camera.CFrame = CFrame.new(Root.Position) * newRotation * CameraOffset
    end
end

UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
    if input.UserInputType == Enum.UserInputType.MouseMovement and not gameProcessedEvent then
        onMouseMove()
    end
end)


1 Like