3rd Person Over The Shoulder Camera

  1. What do you want to achieve? Keep it simple and clear!

I want to achieve a 3rd Person Over The Shoulder Camera where it’s in shiftlock while walking around but free cam when your standing still.

  1. What is the issue? Include screenshots / videos if possible!

Despite my best efforts I can’t get out of shiftlock smoothly and achieve the freecam I want when stationary.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried offsetting the camera and forcing shiftlock but it doesn’t look right. And I don’t know how the free cam part would work. And I have looked for solutions on the dev hub but either none of them work or I’m doing something wrong.

Any help is welcome, thanks!

sorry, forgot the other half of the solution, give me a second

original message

I think you need to locally offset the humanoids camera, not manipulating the camera’s CFrame, but the humanoids cameraOffset or offsetCamera property, I’m not sure which one I last used this property 5 months ago, and then you give it a vector3 offset. :+1:

Humanoid.AutoRotate = false
Humanoid.CameraOffset = vector3.new(x,y,z)
game.GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter

game.GetService("RunService"):BindToRenderStep("ThirdPerson", Enum.RenderPriority.Character.Value, function()
    local _, yAxis = workspace.CurrentCamera.CFrame.Rotation:ToEulerAnglesYXZ()
    Humanoid.RootPart.CFrame = CFrame.new(Humanoid.RootPart.Position) * CFrame.Angles(0,yAxis,0
end)
second half

So you want to make it free cam when you’re standing still but 3rd person when you’re moving?
I’m gonna reopen my old game, because I remember having a similar problem before.

local function thirdPerson(x,y,z)
	
	Humanoid.AutoRotate = false
	Humanoid.CameraOffset = game:GetService("TweenService"):Create(Humanoid, TweenInfo.new(2, Enum.EasingStyle.Quad), {CameraOffset = Vector3.new(x,y,z)}):Play()
	
	game.GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter

	game.GetService("RunService"):RenderStepped:Connect(function()

		if player.Character.Humanoid.MoveDirection.Magnitude == 0 then 

			local _, yAxis = workspace.CurrentCamera.CFrame.Rotation:ToEulerAnglesYXZ()
			Humanoid.RootPart.CFrame = CFrame.new(Humanoid.RootPart.Position) * CFrame.Angles(0,yAxis,0)

		end

	end)

end

game.GetService("UserInputService").InputEnded:Connect(function()
	
	if player.Character.Humanoid.MoveDirection.Magnitude == 0 then
		
		Humanoid.AutoRotate = true
		Humanoid.CameraOffset = game:GetService("TweenService"):Create(Humanoid, TweenInfo.new(2, Enum.EasingStyle.Quad), {CameraOffset = Vector3.new(0,0,0)}):Play()
		
		game.GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
		
	end
	
end)

It should work now, I used a tween to smoothly animate your camera offset and added some events for you that fire when you stop some sort of input for example w then it checks if the player’s character is moving, if its not moving then it resets all of it back to normal. :+1:

1 Like

So i’m confused. Do I combine both the original code and the second half or do I use just the second half?

The second half is the whole complete code, sorry if I didnt explain it. The original message was when I forgot to read about the smooth transition part, so the second message (second point) has all of the code. I didn’t really test it myself but from what I know it should work. :+1:

The code didn’t work at first because the third person function wasn’t being called. So I just fixed it for anyone who wanted to use this in the future:

local player = game.Players.LocalPlayer
local Real = player.Character
local Humanoid = Real.Humanoid
local RS = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local TS = game:GetService("TweenService")
local S = false

local function thirdPerson()
	Humanoid.AutoRotate = false
	local Goal = {}
	Goal.CameraOffset = Vector3.new(2.5,1,1)
	local Tween = TS:Create(Humanoid, TweenInfo.new(2, Enum.EasingStyle.Quad),Goal)
	Tween:Play()

	UIS.MouseBehavior = Enum.MouseBehavior.LockCenter

	RS.RenderStepped:Connect(function()
		if player.Character.Humanoid.MoveDirection.Magnitude > 0 then 
			local _, yAxis = workspace.CurrentCamera.CFrame.Rotation:ToEulerAnglesYXZ()
			Humanoid.RootPart.CFrame = CFrame.new(Humanoid.RootPart.Position) * CFrame.Angles(0,yAxis,0)
		end
	end)
end

local function FreeCam()
	Humanoid.AutoRotate = true
	local Goal = {}
	Goal.CameraOffset = Vector3.new(0,0,0)
	local Tween = TS:Create(Humanoid, TweenInfo.new(2, Enum.EasingStyle.Quad),Goal)
	Tween:Play()

	UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
end

RS.Heartbeat:Connect(function()
	local speed = player.Character.PrimaryPart.Velocity.Magnitude

	if speed > 1 and speed < 16 then
		if S == false then
			S = true
			thirdPerson()
			print("Walking")
		end
	elseif speed <= 1 then
		if S == true then
			S = false
			FreeCam()
			print("Idle")
		end
	end
end)

FreeCam() -- Calling the freecam at the start of the game since your idle.

Credit To Katanasoldier for original script, I just changed some things. (Thank you)

1 Like