I’m trying to create a script that allows my character’s head to track with the camera. It’s working so far, however, once the character starts moving, at the right angle, the head goes into the torso for some reason.
Here’s my client script:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
-- Function to wait for character to fully load
local function waitForCharacter(player)
if player.Character then return player.Character end
return player.CharacterAdded:Wait()
end
local character = waitForCharacter(player)
local head = character:WaitForChild("Head")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local upperTorso = character:WaitForChild("UpperTorso")
local neck = head:FindFirstChild("Neck")
local waist = upperTorso:FindFirstChild("Waist")
local camera = workspace.CurrentCamera
if not neck or not waist then
warn("Neck or Waist Motor6D not found! Make sure the character is R15.")
return
end
-- Default Neck and Waist C0 positions
local neckC0 = neck.C0
local waistC0 = waist.C0
local SMOOTHNESS = 0.2 -- Lower values = smoother movement (0.1 - 0.2 recommended)
local MAX_HEAD_TILT = math.rad(45) -- Limits extreme up/down movement
local MAX_HEAD_SIDE_TILT = math.rad(90) -- Limits extreme left/right movement
local MAX_WAIST_TILT = math.rad(15) -- Limits waist movement
RunService.RenderStepped:Connect(function(dt)
if character and head and humanoidRootPart and upperTorso then
local cameraLookVector = camera.CFrame.LookVector
local bodyLookVector = humanoidRootPart.CFrame.LookVector
-- Calculate vertical and horizontal rotation
local verticalAngle = math.asin(cameraLookVector.y) -- Up/down tilt
local horizontalAngle = math.asin(cameraLookVector.x - bodyLookVector.x) -- Left/right rotation
-- Clamp angles to prevent extreme movement
verticalAngle = math.clamp(verticalAngle, -MAX_HEAD_TILT, MAX_HEAD_TILT)
horizontalAngle = math.clamp(horizontalAngle, -MAX_HEAD_SIDE_TILT, MAX_HEAD_SIDE_TILT)
-- ** Reduce impact of vertical tilt on the neck height**
local adjustedNeckC0 = neckC0 * CFrame.Angles(verticalAngle * 0.75, -horizontalAngle, 0) * CFrame.new(0, -verticalAngle * 0.1, 0)
local adjustedWaistC0 = waistC0 * CFrame.Angles(verticalAngle * 0.5, 0, 0)
-- Smoothly transition to new C0 values
neck.C0 = neck.C0:Lerp(adjustedNeckC0, SMOOTHNESS)
waist.C0 = waist.C0:Lerp(adjustedWaistC0, SMOOTHNESS)
end
end)
Here is what the problem looks like:
Any help would be great!