3rd person arms following the rotation of head/mouse

I currently have a script that is making the head tween towards the player’s cursor that is server sided using Remote Events
I wanted to make the arms follow with the mouse as well so that the player can aim up and down. i had tried many solutions but all of them were local sided and trying to replicate it to be server sided wasnt working out for me at all. i had looked around for a few hours and didnt find anything myself. this is my 2nd day trying to achieve this effect

This is the neck script working on its own. what i wanted to achieve was the players arms following in almost like a viewmodel type style where they arent just pointing out towards the camera and can still have animations played onto it

This is what i had managed to get as close to as i want, but my problem is that i am unable to get this to be server sided

Currently this is the code that im using to make the neck face towards the mouse

Local script

local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local PlayerMouse = Player:GetMouse()
local Camera = workspace.CurrentCamera
local Character = Player.Character or Player.CharacterAdded:Wait()
local Head = Character:WaitForChild("Head")
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Torso = Character:WaitForChild("Torso")
local Neck = Torso:WaitForChild("Neck")



local NeckOriginC0 = Neck.C0

Neck.MaxVelocity = 1/3


RunService.RenderStepped:Connect(function() 
	wait()
	local CameraCFrame = Camera.CoordinateFrame
	if Character:FindFirstChild("Torso") and Character:FindFirstChild("Head") then
		local TorsoLookVector = Torso.CFrame.lookVector
		local HeadPosition = Head.CFrame.p
		if Neck then
			if Camera.CameraSubject:IsDescendantOf(Character) or Camera.CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouse.Hit.p
				local Distance = (Head.CFrame.p - Point).magnitude
				local Difference = Head.CFrame.Y - Point.Y
				local goalNeckCFrame = CFrame.Angles(-(math.atan(Difference / Distance) * 1), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0)
				
				if game.ReplicatedStorage.FetchLocal then
					game.ReplicatedStorage.FetchLocal:FireServer(goalNeckCFrame,NeckOriginC0, mouse.Hit.Position)
				end
			
			end
		end
	end	
end)

Server Script

game.ReplicatedStorage.FetchLocal.OnServerEvent:Connect(function(Player,goalNeckCFrame,NeckOriginC0, Point)
	if Player.Character and Player.Character:WaitForChild("Humanoid").Health > 0 then
		local Character = Player.Character
		local Head = Character:WaitForChild("Torso")
		local Humanoid = Character:WaitForChild("Humanoid")
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Torso = Character:WaitForChild("Torso")
		local Neck = Torso:WaitForChild("Neck")

		if Character:FindFirstChild("Torso") and Character:FindFirstChild("Head") then
			local TorsoLookVector = Torso.CFrame.lookVector
			local HeadPosition = Head.CFrame.p
			if Neck then
				local tweenService = game:GetService("TweenService")
				local tweenInfo = TweenInfo.new(.05, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
				local goal = {C0 = Neck.C0:lerp(goalNeckCFrame*NeckOriginC0, 1 / 1).Rotation + NeckOriginC0.Position}
				local tween = tweenService:Create(Neck, tweenInfo, goal)
				tween:Play()
				
			end
		end
	end
end)
2 Likes

Please instead use :Lerp(), it’ll look smoother and when the player turns really fast it moves fast as well, but near the end it will slow down.

For this though you’d have to update a dictonary with the NeckMotor6d and the newly updated event from the remoteEvent. I suggest making it look something like so:

local motor6ds = {[neckMotor6d] = {["C0"] = ...}}

So you’d need to loop ever frame through all of the moto6ds, then with the dt (delta time, change of time) you will calculate how much you want to :Lerp() it every second. which would be the lerpAmount^(dt).
Let’s put this into perspective, the lerpAmount is 0.5 every second.
So if 1 second passes we want it to have lerped by 0.5.
So if 2 seconds have passed we want to lerp it twice, which would be 0.5 + 0.25 = 0.75
So if 3 seconds have passed we want to lerp it trice, which would be 0.5 + 0.25 + 0.125 = 0.875

Depending on what value you Lerp to what value you have to either use
(1-lerpAmount)^(dt), this is for Lerping the current CFrame to the wanted one.

For lerping the other way around you can just use lerpAmount^dt

Now basically you want to do just add the neckMotor6D / armMotor6D with the calculatedC0 or C1 each time the event fires.

so i sort of got this to work but im back where i was. i managed to get it to now be all Lerp and no Tween and it does look smoother which im glad for but i still havent managed to get the arms to face with the head. for reference i only tried adding one arm for now so that it would be more manageable

if you could give me a hand by telling me what i might be doing wrong that would be great! im still a bit new at manipulating Motor6d’s

Local script

local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local PlayerMouse = Player:GetMouse()
local Camera = workspace.CurrentCamera
local Character = Player.Character or Player.CharacterAdded:Wait()
local Head = Character:WaitForChild("Head")
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Torso = Character:WaitForChild("Torso")
local Neck = Torso:WaitForChild("Neck")
local LeftSh = Torso:WaitForChild("Left Shoulder")
local RightSh = Torso:WaitForChild("Right Shoulder")
local Larm = Character:WaitForChild("Left Arm")
local Rarm = Character:WaitForChild("Right Arm")


local ShoulderRightOriginC0 = RightSh.C0
local ShoulderLeftOriginC0 = LeftSh.C0
local NeckOriginC0 = Neck.C0

Neck.MaxVelocity = 1/3

local lerpamount = 0.1
RunService.RenderStepped:Connect(function() 
	local CameraCFrame = Camera.CoordinateFrame
	if Character:FindFirstChild("Torso") and Character:FindFirstChild("Head") then
		local TorsoLookVector = Torso.CFrame.lookVector
		local HeadPosition = Head.CFrame.p
		if Neck then
			if Camera.CameraSubject:IsDescendantOf(Character) or Camera.CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouse.Hit.p
				
				local DistanceNeck = (Head.CFrame.p - Point).magnitude
				local DifferenceNeck = Head.CFrame.Y - Point.Y
				local goalNeckCFrame = CFrame.Angles(-(math.atan(DifferenceNeck / DistanceNeck) * 1), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0)
				local DistanceRight = (Rarm.CFrame.p - Point).magnitude
				local DifferenceRight = Rarm.CFrame.Y - Point.Y
				local goalRightCFrame = CFrame.Angles(-(math.atan(DifferenceRight / DistanceRight) * 1), (((Rarm.Position - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0)
				
				
				
				
				local startedtime = os.clock()
				local tbl = {[Neck] = {["C0"] =  Neck.C0:lerp(goalNeckCFrame*NeckOriginC0, 1 / 1).Rotation + NeckOriginC0.Position},
				[RightSh] = {["C0"] =  RightSh.C0:lerp(goalRightCFrame*ShoulderRightOriginC0, 1 / 1).Rotation + ShoulderRightOriginC0.Position}
				}
				
				for i,v in pairs(tbl) do
					local Deltatime = os.clock() - startedtime
					local lerpp = (1-lerpamount)^(Deltatime)
					local dir = i.C0:lerp(v["C0"], lerpp)
					game.ReplicatedStorage.FetchLocal:FireServer(mouse.Hit.Position,dir, i)
				end
				
			
			end
		end
	end	
end)

Server Script

game.ReplicatedStorage.FetchLocal.OnServerEvent:Connect(function(Player,Point,dir, motor)
	if Player.Character and Player.Character:WaitForChild("Humanoid").Health > 0 then
		local Character = Player.Character
		local Head = Character:WaitForChild("Torso")
		local Humanoid = Character:WaitForChild("Humanoid")
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Torso = Character:WaitForChild("Torso")
		if Character:FindFirstChild("Torso") and Character:FindFirstChild("Head") then
			if motor then
				motor.C0 = dir
			end
		end
	end
end)

Nevermind my problem is different now, for some reason it is working just not locally? i dont get how that would work

Found the problem on my own for this one, apparently i just needed to change the name locally for the shoulder motors lol

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