Keeping the mouse at a certain position on the screen for a camera system?

This is the first time I’ve worked on a camera system, so sorry if I’m posting a dumb or wrong question.

I’m trying to make a 3rd person camera system similar to PolyGuns.
https://gyazo.com/519a9c66014a792fcd0326bba01c7c58

This is what I have so far.
https://gyazo.com/42c3e27c9ae895b499dc1cce4756994c

The only main difference I can see is that my mouse is able to move where ever, while in Polyguns it’s stuck in the centre of the screen. I’ve googled around, but I couldn’t find anything on doing that.

How would I go about doing that?

3 Likes

I just realised the camera doesn’t look up or down either. Maybe I should sort that out first!

I think they’re using a modified camera control script (one of Roblox’s core scripts.)

You can forcefully enable mouse lock switch through it and then disable toggling mouse lock switch under StarterPlayer.

1 Like

So I’d basically have to scrap the code I already have an modify the roblox one?

Don’t think i’m up for that or capable enough to do that haha rip me.

If you’re just looking for a good third person camera system, I can send you the actual script. Though to set it up to be forcing mouse-lock-switch isn’t very complicated.

There’s a few values you have to change and that’s about it.

Trying to do it myself so I can improve + feel like i’ve accomplished something, but I might have to have a look at it; if that’s alright.

Right now though, my problem seems to be Camera.Focus isn’t working properly.

Camera.Focus = Mouse.Hit
Camera.Focus = CFrame.new(Mouse.Hit.p)

neither of those seem to be working which is odd.

The problem is , is I don’t think you can set the focus to the mouse. There are ways of setting the camera to not be able to go along a certain plane, but I haven’t figured that out yet.

Anyways,

Here’s the tutorial I watched to get the third person camera:

What did you expect Camera.Focus to do? Camera.Focus is only used by the engine for optimizations and for :GetLargestCutoffDistance. Other than that, setting focus does nothing.

Oh, and to lock the mouse to the center, you need to set UserInputService.MouseBehaior to LockCenter.

I haven’t really done much camera manipulation so my bad. Just read the wiki page on Camera.Focus and see what it’s use now.

Do I have to keep setting

UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

Because it only seems to work when it’s in some sort of loop, if I just set it with all my other variables it won’t lock to the center.

Annnnd, my friend told me to change Focus to CFrame, which I did. But now it does this & I have no idea why. The gif is with the MouseBehavior set outside of a loop. If I set the MouseBehavior inside the loop then it’ll stick to the centre, but the camera won’t move and stuff.

https://gyazo.com/cc8951fecad72c35ee1c53ba523fafb6

I’m pretty clueless with camera manipulation so sorry if my questions are dumb or not explained that well!

If you set Focus to be the same as CFrame, Roblox will think you’re zoomed into first person.

You should set camera.CameraType to Enum.CameraType.Scriptable. This will tell Roblox’s CameraScript not to mess with the camera. Then you should bind to “RenderStep”:

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local function onRenderStep(dt)
    local camera = workspace.CurrentCamera
    camera.CFrame = whatever --this can be something like humanoidRootPart.CFrame * CFrame.Angles(pitch, yaw, 0)

    UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter --this locks the mouse to the center
end

local function onInputChanged(inputObj, wasProcessed)
    if inputObj.UserInputType == Enum.UserInputType.MouseMovement then
        yaw = yaw + inputObj.Delta.Position.X * sensitivityX --use Delta, not Position!
        pitch = pitch + inputObj.Delta.Position.Y * sensitivityY
    end
end

--Now hook up your callback functions
RunService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, onRenderStep)
UserInputService.InputChanged:Connect(onInputChanged)
1 Like

I already have it set to Scriptable, but after looking at CoordinateFrame on the wiki, I release it’s deprecated and camera.CFrame does the exact same.

Gonna start from the beginning again because I realised I misunderstood what certain things do, i’ll be back soon!

x_o locks the mouse and then checks the delta to see how much to move it. Sadly though, I forget what exactly he’s doing to move it after that. But the characters are all moved with CFrame that he made and uses for the character controller. #PerksOfBeingHeadModeratorForMailboxGames

This is exactly what you want:

-------------
--- INDEX ---
-------------

--Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

--Player & Character
local localPlayer = game:GetService("Players").LocalPlayer

--Other
local Camera = game:GetService("Workspace").CurrentCamera

--------------
--- VALUES ---
--------------

local xAngle = 0
local yAngle = 0
local cameraPos = Vector3.new(3.5,0,7.5)

----------------------
--- INITIALIZATION ---
----------------------

wait(1)
Camera.CameraType = Enum.CameraType.Scriptable
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

-----------------
--- FUNCTIONS ---
-----------------

userInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		xAngle = xAngle-input.Delta.x*0.4
		--Clamp the vertical axis so it doesn't go upside down or glitch.
		yAngle = math.clamp(yAngle-input.Delta.y*0.4,-80,80)
	end
end)

runService.RenderStepped:Connect(function()
	local Character = localPlayer.Character
	local rootPart = Character:FindFirstChild("HumanoidRootPart")
	if Character and rootPart then
		--Set rotated start cframe inside head
		local startCFrame = CFrame.new((rootPart.CFrame.p + Vector3.new(0,2,0)))*CFrame.Angles(0, math.rad(xAngle), 0)*CFrame.Angles(math.rad(yAngle), 0, 0)
		
		--Set camera focus and cframe
		local cameraCFrame = startCFrame + startCFrame:vectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,cameraPos.Z))
		local cameraFocus = startCFrame + startCFrame:vectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,-50000))
		
		Camera.CFrame = CFrame.new(cameraCFrame.p,cameraFocus.p)
	end
end)

This script is made to work inside StarterPlayerScripts, but you can also put it in PlayerGui or StarterPack.

6 Likes

Thank you very much! I’ll test it when I get home. Quick question though, why do these two wiki pages say different things to what focus is?

I don’t know, maybe the behaviour on the left is default and the one on the right when the camera is set to “Scriptable”? :thinking:

It works! Not 100% what I wanted it to be like, but it’s a good start & i’m gonna spend the next day figuring out all the mathy bits (terrible at anything math related on roblox). Ty very much!

1 Like

Yeah, that thing on the left only applies to certain CameraTypes. In Scriptable, the only thing controlling the position and orientation of the camera is the CFrame property.

Hi, is there any way I can add camera collisions for this?