Need help smoothly transitioning between third and custom first-person camera

Making this post as a sort of piggyback off another recent post of mine:

I’ve come to the realization that the best way to lay the groundwork for this effect comes with creating an entirely custom first-person camera system to have a lot more control over the camera and it’s orientation.

If I was making a strictly first-person shooter, then it would have been as simple as forking one of the many custom first-person camera scripts on the Devforum; however I’d like my game to feature both third-person and first-person capabilities, and smoothly transition between the two—which is what is lacking in the existing scripts I’ve found.

So, I decided to take a crack at making my own with the assistance of the other scripts before me. Unfortunately I’m mathematically challenged but this is what I could get on my own:

Here's the code, LocalScript in StarterPlayerScripts:
local player = game.Players.LocalPlayer
player.CharacterAppearanceLoaded:Wait()
local Character = player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local rootPart = Character:WaitForChild("HumanoidRootPart")

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

local mouse = player:GetMouse()
local Camera = workspace.CurrentCamera

local firstPerson = false

local function IsFirstPerson()
	return Character.Head.LocalTransparencyModifier == 1
end

local function toggleFirstPerson(active)
	if active then
		firstPerson = true
		Humanoid.AutoRotate = false
		Camera.CameraType = Enum.CameraType.Scriptable
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	elseif not active then
		firstPerson = false
		Humanoid.AutoRotate = true
		Camera.CameraType = Enum.CameraType.Custom
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	end
end

local cameraAngleX = 0
local cameraAngleY = 0

local function mouseMove(MouseDelta)
	cameraAngleX = cameraAngleX - MouseDelta.X
	cameraAngleY = math.clamp(cameraAngleY - MouseDelta.Y, -80, 80)--math.clamp(cameraAngleY-UserInputService:GetMouseDelta().Y, -80, 80)
end

RunService.RenderStepped:Connect(function()
	local FirstPersonCheck = IsFirstPerson()
	local MouseDelta = UserInputService:GetMouseDelta()
	mouseMove(MouseDelta)
	
	if FirstPersonCheck then
		if not firstPerson then
			toggleFirstPerson(true)
		end
		
		local startCFrame = CFrame.new(rootPart.CFrame * CFrame.new(0, 1.5, 0.5).Position)
		local lookAngle = (CFrame.Angles(0, math.rad(cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngleY), 0, 0))
		Camera.CFrame = startCFrame * lookAngle
	else
		if firstPerson then
			toggleFirstPerson(false)
		end
		
	end
end)	

mouse.WheelBackward:Connect(function()
	if firstPerson then
		toggleFirstPerson(false)
	end
end)

The primary reason for this post is that I need help solving that jolting caused by the difference of the camera’s angle between the two states, because currently the transition is way too jarring to be acceptable in gameplay. To clarify, the default Roblox third-person camera fits my needs fine, it’s just the first-person camera that I needed to make custom, and I’d really appreciate some help in making the first-person camera work off the angles that the third-person camera was at. I have hardly any idea how mouse Delta works so this might be an easy fix.

In the event that someone can help solve this I hope to make some kind of Community Resource post combining what I’ve learned over these agonizing couple weeks so others in the future can achieve what I’m trying to do with considerably less headaches :slight_smile:

2 Likes