Positioning the camera to the head

Recently I played Parkour Reborn and wondered how they did their camera.
https://gyazo.com/508f0c017d1e0325d1ffd153b84ca6cb
https://gyazo.com/82c1f35b86d4e1f1f7760bf368dd53c8

The camera moves along with the head and if the head rotates, the camera rotates with it as well.

This can’t be a renderstepped cframe change to the head since then u wouldn’t have any control over your camera. I was wondering how would one actually accomplish this (since its clearly possible).

I’ve searched throughout the entire forum but found nothing that gives the same result.

You can set the camera CFrame to the CFrame of the users head as their character spawns in
That game not only does that though it has its own motion and camera moving system to make it move smoothly compared to how roblox would allow you
Take a look here for more info:
Camera | Documentation - Roblox Creator Hub

The camera is manually positioned to Character.Head’s CFrame on RenderStepped - this makes the camera follow the perspective of the head correctly and rotate/tilt with each of the character’s animations (they have custom movement animations to make sure the head moves smoothly). Assuming it’s a parkour game with complex movement they may even bend/position body parts manually to line up with surfaces they’re jumping off and/or force the head to look around smoothly.

When the camera is forced all the way in like this, your character automatically rotates in the direction the camera is facing, so controlling the character feels a little odd when hold the left/right movement keys. With this method you may have to manually rotate the character to avoid this behaviour.

In addition, the camera rotates slightly depending on how far left/right/up/down the mouse is from the centre of the screen. General tweaks & smoothing applied so the camera doesn’t jerk around and make the player sick.

It may look something like this (put this in a LocalScript in StarterCharacterScripts):

local p = game.Players.LocalPlayer
local c = p.Character or p.CharacterAdded:Wait()
local cam = game.Workspace.CurrentCamera
local m = p:GetMouse()

cam.FieldOfView = 80
c.Humanoid.AutoRotate = false

--- Hide the player's accessories in first person, or they will cover our screen!
for i,v in pairs(c:GetChildren()) do
	if v:IsA("Accessory") then
		v:Destroy()
	end
end

game:GetService("RunService").RenderStepped:Connect(function(delta)
	if c and c:FindFirstChild("Head") then
		
		local mouse_position = Vector2.new(m.X,m.Y)
		
		---- Calculate how far from the centre of the screen the player's mouse is
		local screen_size = cam.ViewportSize
		local mouse_centre_offset = (mouse_position/screen_size)-Vector2.new(0.5,0.5)
		
		local mouse_camera_rotation = CFrame.Angles(-mouse_centre_offset.Y,-mouse_centre_offset.X,0)
		
		cam.CFrame = c.Head.CFrame*CFrame.new(0,0.25,-0.375)*mouse_camera_rotation
	end
end)

(My running animation pack from Roblox is very jerky, you can see how that comes out with this custom camera! - that’s why you need custom animations.)


1 Like

After a lot of forking with the default camera scripts I came up with a method that actually works https://gyazo.com/4340c4498f1ad6771ceeabcc1e18f721
https://gyazo.com/11bcfe5a271f8f13687a893f2d49a717
https://gyazo.com/f93012ed4d64b677342e519db17d0dac the original animation
@topcst

The way it works is pretty simple. U create a buffer camera which will store the actual camera position that Roblox thinks it should be in. The Current Camera is whats used for all the post-buffer-calculations. All you have to do is multiply your buffer’s cframe by another cframe which consists of 3 things:
the X and Z axis which are the easiest to do and the Y axis which was a bit of a nightmare to figure out.
The X and Z axis are simple. All you have to do is get the X and Z axis rotation from the head’s cframe with :ToOrientation() and u can plug it into the final cframe that u add to the buffer camera’s cframe.
The Y axis is the combination of 3 motor6d’s transform Y rotations.
You have to get the Y axis rotation with :ToOrientation() from the Transform property of all the 3 motor6d’s which are: Waist (Upper Torso), Root (Lower Torso), Neck (Head).
The final code looks like this (besides all the buffer changes that you have to manually do)

local x1,y1,z1 = game.Players.LocalPlayer.Character:WaitForChild("Head").CFrame:ToOrientation()
		
		local x2,y2,z2 = game.Players.LocalPlayer.Character:WaitForChild("Head").Neck.Transform:ToOrientation()
		local x3,y3,z3 = game.Players.LocalPlayer.Character:WaitForChild("LowerTorso").Root.Transform:ToOrientation()
		local x4,y4,z4 = game.Players.LocalPlayer.Character:WaitForChild("UpperTorso").Waist.Transform:ToOrientation()

		-- Here is where the new CFrame and Focus are set for this render frame
		local currentCamera = game.Workspace.CurrentCamera :: Camera
		game.Players.LocalPlayer.PlayerScripts.PlayerModule.CameraCFrame.CFrame = newCameraCFrame
		game.Players.LocalPlayer.PlayerScripts.PlayerModule.CameraCFrame.Focus = newCameraFocus
		currentCamera.CFrame = newCameraCFrame * CFrame.Angles(x1, y2+y3+y4,z1)
		currentCamera.Focus = newCameraFocus * CFrame.Angles(x1, y2+y3+y4,z1)

I also disabled zooming in making all your body parts invisible. If you want to reenable it go to line 155 in Transparency Controller and delete it.
PlayerModule.rbxm (129.8 KB)
Here’s the model so you can try it out yourself

2 Likes

Now it has errors since I didn’t bother accounting for edge cases where the character isnt loaded in and there are a couple things I still want to do with it but the foundation is built

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.