How to tilt the Torso on an R6 RigType so it faces the Camera direction?

I have an FPS game I’m currently working on, and I’ve been stumped, searching the forum all last night and earlier today trying to find a solution, though all have not met my use case.

I want to create a system where when the Player looks down in first person, other people can see their body tilt when they look down, or up. I don’t want the player to look at the mouse position, and I do not want the player to turn and face the camera when playing the game. I just want other players to be able to see them look up or down, bending only the Torso.

My game needs this so people know where others are aiming with their Gun. I don’t wish for the head to look at the camera either. Only for it to bend the Torso on the Y axis, but I haven’t been able to figure it out. I intend on making the server handle this rotation, don’t ask why but it’s required for what I’m doing. I really don’t want hardcoded client scripts.


Anyway with that out of the way, I sincerely thank you for the help If I get any, DevForum spotlighting posts can be pretty bad at times.

Bump, still need help with this.

The First Person Element Of A First Person Shooter - Resources / Community Tutorials - DevForum | Roblox

check out then replicating weapon movement section.

Bending the Torso with an R6 rig is impossible, as there is no Waist joint.

So, unfortunately, moving the head and arms is the only way for people to see where an R6 rig is looking.

I have scripted something here which will rotate the head towards the cameras LookVector, and will replicate the effect for everyone else to see. It also works with both R15 and R6, with the only difference being that the R15 version rotates the torso too.

I do have a different version of this script, that only works with R6, but it also rotates the arms.
Screenshot (458)
Screenshot (459)

Thanks for the reply!

I was nearing this conclusion due to the fact that everybody who posted about this didn’t seem to try and achieve this effect at all, and I was beginning question if I’d be the first to talk about it, but it being impossible sums up my confusion pretty well.

I believe since Rotating the Head and Arms is the only solution, I’ll be going with that. I’ll likely take a look at what you’ve linked to see if it’s okay to use and stuff and I appreciate it tons. Thanks! love the avatar btw!

For the head and arm rotation, as it isnt part of the script i linked, heres the exact code i used:

LocalScript, parented to StarterCharacterScripts:

local RunService = game:GetService('RunService')
-- LookEvent is parented to the LocalScript
local Event = script:WaitForChild('LookEvent')
local Player = game.Players.LocalPlayer
local Camera = workspace:WaitForChild('Camera')
local Character = Player.Character or Player.CharacterAdded:Wait()
local Head = Character:WaitForChild('Head')
local Humanoid = Character:WaitForChild('Humanoid')
local RootPart = Character:WaitForChild('HumanoidRootPart')
local Torso = Character:WaitForChild('Torso')
local Neck = Torso:WaitForChild('Neck')

local Ang = CFrame.Angles
local aSin = math.asin
local aTan = math.atan

local NeckOrgnC0 = Neck.C0
local HeadHorFactor = 0
local HeadVertFactor = 1
local UpdateSpeed = 0.5

while task.wait(1/60) do
	local CameraCFrame = Camera.CoordinateFrame
	local MouseOriginPosition = Player:GetMouse().Origin.Position
	if Humanoid.Health > 0 then
		Event:FireServer(CameraCFrame, HeadHorFactor, HeadVertFactor, UpdateSpeed, MouseOriginPosition)
	end
end

Normal Script, Parented to LocalScript

local Event = script.Parent:WaitForChild('LookEvent')
local Ang = CFrame.Angles
local aSin = math.asin
local aTan = math.atan

local Character = script.Parent.Parent
local Head = Character:WaitForChild('Head')
local LeftArm = Character:WaitForChild('Left Arm')
local RightArm = Character:WaitForChild('Right Arm')
local Humanoid = Character:WaitForChild('Humanoid')
local RootPart = Character:WaitForChild('HumanoidRootPart')
local Torso = Character:WaitForChild('Torso')
local Neck = Torso:WaitForChild('Neck')
local NeckOrgnC0 = Neck.C0
local RightShoulder = Torso:WaitForChild('Right Shoulder')
local RightShoulderOrgnC0 = RightShoulder.C1
local LeftShoulder = Torso:WaitForChild('Left Shoulder')
local LeftShoulderOrgnC0 = LeftShoulder.C1

Event.OnServerEvent:Connect(function(Player, CameraCFrame, HeadHorFactor, HeadVertFactor, UpdateSpeed, MouseOriginPosition)
	if Humanoid.Health > 0 then
		local Dist = (Head.CFrame.Position-CameraCFrame.Position).Magnitude
		local Diff = Head.CFrame.Y-CameraCFrame.Y
		
		local HeadPosition = Head.CFrame.Position
		
		local LeftArmPosition = LeftArm.CFrame.Position
		
		local RightArmPosition = RightArm.CFrame.Position
		
		local TorsoLookVector = RootPart.CFrame.lookVector
		
		
		local X = -(math.asin((MouseOriginPosition - CameraCFrame.Position).unit.y)) * -1
		
		--Neck.C0 = Neck.C0:Lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HeadPosition-MouseOriginPosition).Unit):Cross(TorsoLookVector)).Y*HeadHorFactor),UpdateSpeed/2)
		
		local _, Y, Z = Neck.C0:ToEulerAnglesXYZ()
		Neck.C0  = CFrame.new(Neck.C0.Position) * CFrame.Angles(X - 1.5, Y, Z)
		
		local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
		local OldRightC0 = RightShoulder.C0
		RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)
		
		local _, Y, Z = LeftShoulder.C0:ToEulerAnglesXYZ()
		LeftShoulder.C0 = CFrame.new(LeftShoulder.C0.Position) * CFrame.Angles(X, Y, Z)
	end
end)
1 Like

I forgot to reply but this is the exact functionality I was looking for. I went ahead and re-named + restructured the code to make it more recognizable for me and I added a few extra checks so it doesn’t always replicate depending on certain scenarios. I really needed this, thank you!!