I’ve tried a lot of things. Here is what is happening:
In the character, I have a localscript that points the characters upperRightArm and Head at the Mouse.hit.p. I use some typical math for this. (I found these scripts elsewhere in the forum, and changed them some - they didn’t work for me as they were).
In the ServerScriptService, I have a script that catches these changes to the shoulder, and broadcasts them across the server to the other clients, so others can see where my character is pointing/looking
It works pretty well most of the time, but maybe 1 in 3 times, it will not lift the gun very high - so if he is pointing at your head it looks like he is pointing at your foot or knees or lowerTorso…(no good)
I have disabled the idle animation, in case that was messing with it. I have made my own idle animation, that has him pointing the gun at shoulder level… still, 1 in 3 times (or so) it will not lift the gun high enough.
Even when it works, it’s still not perfect - if he’s aiming at your head, you will see him aiming at your chest - I’d like even that to work better.
In the Character in a 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()
wait(2)--added 11.13.21 to try to fix error
local UpperTorso
local LowerTorso
local Head
local Waist
local Neck
local rightUpperArm
local rightShoulder
local leftUpperArm
local leftShoulder
local Humanoid
local HumanoidRootPart
if not Player:FindFirstChild("InMenu") then--added 11.13 to try to fix error
repeat wait(.3)
Character = Player.Character or Player.CharacterAdded:Wait()
UpperTorso = Character:WaitForChild("UpperTorso")
LowerTorso = Character:WaitForChild("LowerTorso")
Head = Character:WaitForChild("Head")
Waist = UpperTorso:FindFirstChild("Waist") or LowerTorso:FindFirstChild("Waist")
Neck = UpperTorso:FindFirstChild("Neck") or Head:FindFirstChild("Neck")
rightUpperArm = Character:WaitForChild("RightUpperArm")
rightShoulder = rightUpperArm:FindFirstChild("RightShoulder") or UpperTorso:FindFirstChild("RightShoulder")
leftUpperArm = Character:WaitForChild("LeftUpperArm")
leftShoulder = leftUpperArm:FindFirstChild("LeftShoulder") or UpperTorso:FindFirstChild("LeftShoulder")
Humanoid = Character:WaitForChild("Humanoid")
HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
until UpperTorso and LowerTorso and Head and Neck and rightUpperArm and rightShoulder and leftUpperArm and leftShoulder
--
local NeckOriginC0 = Neck.C0
local WaistOriginC0 = Waist.C0
local rightShoulderOriginC0 = rightShoulder.C0
local leftShoulderOriginC0 = leftShoulder.C0
local UserInputService = game:GetService("UserInputService")
Neck.MaxVelocity = 1/3
if (UserInputService.MouseEnabled) then
RunService.RenderStepped:Connect(function()
local CameraCFrame = Camera.CFrame
if Character:FindFirstChild("UpperTorso") and Character:FindFirstChild("Head") then
local TorsoLookVector = UpperTorso.CFrame.lookVector
local HeadPosition = Head.CFrame.p
local rightUpperArmPosition = rightUpperArm.CFrame.p
local leftUpperArmPosition = leftUpperArm.CFrame.p
if rightShoulder 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
rightShoulder.C0 = rightShoulder.C0:lerp(rightShoulderOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 1.3), 0, 0), 0.5 / 2)
Neck.C0 = Neck.C0:lerp(NeckOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance)), 0, 0), 0.5 / 2)
end
end
if leftShoulder 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
leftShoulder.C0 = leftShoulder.C0:lerp(leftShoulderOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((leftUpperArmPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0), 0.5 / 2)
end
end
game.ReplicatedStorage.AdjustPlayerOnServer:FireServer(Neck.C0,rightShoulder.C0,leftShoulder.C0)
end
end)
end
end
In the Server Script in ServerScriptService:
game.ReplicatedStorage.AdjustPlayerOnServer.OnServerEvent:Connect(function(player,neckC0,rightShoulderC0,leftShoulderC0)
local neck = player.Character.Head:FindFirstChild("Neck") or player.Character.UpperTorso:FindFirstChild("Neck")
local rShoulder = player.Character.RightUpperArm:FindFirstChild("RightShoulder") or player.Character.UpperTorso:FindFirstChild("RightShoulder");
local lShoulder = player.Character.LeftUpperArm:FindFirstChild("LeftShoulder") or player.Character.UpperTorso:FindFirstChild("LeftShoulder");
neck.C0 = neckC0;
rShoulder.C0 = rightShoulderC0;
lShoulder.C0 = leftShoulderC0;
end)
It would be nice if I could rid of the random large error, wherein he barely lifts his tool. But I’d also like to make it more accurate when it works. I’m not great at the vector math or whatever I’m doing inside the LERP in the LocalScript. I’ve adjusted it some, and the
rightShoulder.C0 = rightShoulder.C0:lerp(rightShoulderOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 1.3), 0, 0), 0.5 / 2)
is about the best I’ve gotten it to perform.
Any ideas, I’m trying to not switch to a viewmodel system, I’d like to keep it kind of simple. BUT in the case that I have to do so, does anyone have a favorite viewmodel/AimDownSights system they use currently, and it works for you ? Please let me know that too. I’ve seen EgoMoose’s, but its a few years old and I’m not sure if it’s outdated yet.
Any help apprec.
Kind humble thanks !