Third Person Camera Script

@DeepBlueNoSpace
Actually, I am currently working on tutorials, lol
I’ll do one on explaining OTS camera creation very soon
Also, I can’t access your system since my group spaces are full, so rip

@DevChris
Thanks! Will take that into account the next time I edit this

2 Likes

I don’t know if this still works, but…

2 Likes

Most definitely busted at that part - I’ll fix it in a while
Thanks for mentioning!

6 Likes

This doesn’t work, put it into StarterGUI but then nothing happened.

2 Likes

u need put this in StarterPlayerScripts and name this “CameraScript”

I just saw the start code and I was thinking you should change it after reading:

repeat wait() until Player.Character
repeat wait() until Player.Character.Humanoid
repeat wait() until Player.Character.HumanoidRootPart

Yeah, I tried it but now the camera is still and doesn’t move with the character.

You can still “disable” the default Roblox camera module by going in studio and testing the game. While testing the game in studio, you can go in StarterPlayer > StarterPlayerScripts and find “PlayerModule.” You can copy that and then stop testing. Right after you stop testing, you’ll want to paste the PlayerModule in StarterPlayerScripts. You’ll want to go in the PlayerModule and delete this line below
self.controls = require(script:WaitForChild("CameraModule"))

You’ll also want to delete this line
function PlayerModule:GetCameras() return self.cameras end

After you did all that, you can insert OP’s Orbital script and test it for yourself!

2 Likes

What can I do, if i dont want to move the character around with the camera

Hello.

Below is old.

I get this error here:
CameraScript is not a valid member of PlayerScripts

As there is no CameraScript inside PlayerScripts.
image

Is the script outdated or what seems to be the problem?

Looking forward to your answer. Thank you, sincerely.

Above is the old error, just ignore it.

I did what @ByDiego7w7 did,

And it didnt error, and something happened with the cam, but. The player doesnt move with the camera and etc.

@PineappleDoge1 solution didn’t help, since there is no playerModule in the player when you have the CameraScript inside.

StarterPlayerScripts without CameraScript:
image

And with:
image

Oh no, never mind. I maybe it is supposed to be like it is now. Since it is orbital, it is not supposed to be like shiftlock right?

But is there any way to do that? So the character moves with camera?

Hey, I tried that. But I think the playerModule gets deleted when using this other script, as I did not find it.

If you go through the code and try to find:

local CamScript = Player.PlayerScripts.CameraScript
CamScript.Disabled = true

I found that if you delete it, the script works perfectly fine.

1 Like

I have updated the code for anyone that wants to use it, and I also made it as a module so you can Start() and Stop() the camera script, however, there is a bug where the camera no longer moves after un-focusing the window.

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

local Camera = Workspace.CurrentCamera
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")

local OrbitalCamera = {
	settings = {
		popper = false,
		sensitivity = Vector2.new(120, 120),
		offset = CFrame.new(2, 3, 15),
		verticalLimit = NumberRange.new(-5 * math.pi / 12, 5 * math.pi / 12),
		combinations = {
			{true, false, false, false, 0, 0},
			{true, true, false, false, math.pi / 4},
			{false, true, false, false, math.pi / 2},
			{false, true, true, false, 3 * math.pi / 4},
			{false, false, true, false, math.pi},
			{false, false, true, true, 5 * math.pi / 4},
			{false, false, false, true, 3 * math.pi / 2},
			{true, false, false, true, 7 * math.pi / 4}
		}
	}
}

local DeltaX = 0
local DeltaY = 0

local AngleH = 0
local AngleV = 0

local W = false
local A = false
local S = false
local D = false

local RenderStepped = nil
local InputChanged = nil
local InputBegan = nil
local InputEnded = nil

function OrbitalCamera:Start()
	Humanoid.AutoRotate = false
	Camera.CameraType = Enum.CameraType.Scriptable
	UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	RenderStepped = RunService.RenderStepped:Connect(function()
		AngleH = AngleH - DeltaX / self.settings.sensitivity.X
		DeltaX = 0
		AngleV = math.clamp(AngleV - DeltaY / self.settings.sensitivity.Y, self.settings.verticalLimit.Min, self.settings.verticalLimit.Max)
		DeltaY = 0
		local finalCFrame = CFrame.new(HumanoidRootPart.Position) * CFrame.Angles(0, AngleH, 0) * CFrame.Angles(AngleV, 0, 0) * self.settings.offset
		if self.settings.popper then
			local direction = (finalCFrame.Position - Head.Position).Unit * ((self.settings.offset.Position).Magnitude)
			local raycastResult = Workspace:Raycast(Head.Position, direction)
			if raycastResult then
				local distance = (raycastResult.Position - finalCFrame.Position).Magnitude
				finalCFrame = finalCFrame * CFrame.new(0, 0, -distance)
			end
		end
		Camera.CFrame = finalCFrame
		if W or A or S or D then
			for _, value in pairs(self.settings.combinations) do
				if value[1] == W and value[2] == A and value[3] == S and value[4] == D then
					local directionVector = Camera.CFrame.LookVector
					local targetCFrame = CFrame.new(HumanoidRootPart.Position, HumanoidRootPart.Position + Vector3.new(directionVector.X, 0, directionVector.Z))
					HumanoidRootPart.CFrame = HumanoidRootPart.CFrame:Lerp(targetCFrame * CFrame.Angles(0, value[5], 0), 0.25)
				end
			end
		end
	end)
	InputChanged = UserInputService.InputChanged:Connect(function(input, gameProcessedEvent)
		if not gameProcessedEvent then
			if input.UserInputType == Enum.UserInputType.MouseMovement then
				if DeltaX ~= input.Delta.X then
					DeltaX = input.Delta.X
				end
				if DeltaY ~= input.Delta.Y then
					DeltaY = input.Delta.Y
				end
			end
		end
	end)
	InputBegan = UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
		if not gameProcessedEvent then
			if input.KeyCode == Enum.KeyCode.W then
				W = true
			elseif input.KeyCode == Enum.KeyCode.A then
				A = true
			elseif input.KeyCode == Enum.KeyCode.S then
				S = true
			elseif input.KeyCode == Enum.KeyCode.D then
				D = true
			end
		end
	end)
	InputEnded = UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
		if not gameProcessedEvent then
			if input.KeyCode == Enum.KeyCode.W then
				W = false
			elseif input.KeyCode == Enum.KeyCode.A then
				A = false
			elseif input.KeyCode == Enum.KeyCode.S then
				S = false
			elseif input.KeyCode == Enum.KeyCode.D then
				D = false
			end
		end
	end)
end

function OrbitalCamera:Stop()
	Humanoid.AutoRotate = true
	Camera.CameraType = Enum.CameraType.Custom
	UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	if RenderStepped then RenderStepped:Disconnect() end
	if InputChanged then InputChanged:Disconnect() end
	if InputBegan then InputBegan:Disconnect() end
	if InputEnded then InputEnded:Disconnect() end
end

return OrbitalCamera

Example

local OrbitalCamera = require(script:WaitForChild("OrbitalCamera"))
OrbitalCamera:Start()
4 Likes

im getting a bug where the camera detaches from the player and it just sits there as you can move around the player

I am not sure what’s wrong with it, it would be nice if you could send me reproduction file or steps so I can look into it.

The camera is stuck in one spot you can move the player but not look around allowing the player to run off the screen
image

3 Likes

OMG Thanks for this!

its soooo helpful for me i was trying to make a camera exactly like this and had MANY problems now everything is easy as pie … i mean cake

i found a bug

--here is my script
local cam = require(script.Parent:WaitForChild("ModuleScript"))
cam:Start()

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()

char:WaitForChild("Humanoid"):GetPropertyChangedSignal("Sit"):Connect(function()
	if char.Humanoid.Sit == true then
		cam:Stop()
	else
		cam:Start()
	end
end)

so when the player sits then he stand the mouse dont lock anymore

also found a bug in popper cam where the camera check for collisions in character and does a weird behaviour

3 Likes

I got it working but it breaks when you leave the tab and go back in

i also got another bug when the player dies it just breaks it infinitely repeats Head is not a valid member of Model “lootlamabud” and it just repeats that for ever

How can I use this script to make it only start when a tool is equipped? Thank you.