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)
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)