I’m making a gun system and I weld the guns to the torso. I want to make it so that when you look up and down the gun and hands and head go with it. It all works except for the fact that the gun becomes slightly offset. I want the gun to remain in the same exact relative location to the arms at all times and I am not sure how to do this as I am terrible at geometry. If there is a formula or script or anything I can take a look at please help me out.
I can’t use the C1 property on the tool as it offsets animations so it has to be the position and rotation of the C0 property.
My code:
local stance = self:GetHumanoidState("Stance")
local itemData, item = self:GetCurrentItemData()
local baseNeckCFrame:CFrame = self.BaseNeck
local baseRightShoulderCFrame:CFrame = self.BaseRightShoulder
local baseLeftShoulderCFrame:CFrame = self.BaseLeftShoulder
local neckOffset = self:GetHumanoidState("N") or CFrame.identity
local rightShoulderOffset = self:GetHumanoidState("RS") or CFrame.identity
local leftShoulderOffset = self:GetHumanoidState("LS") or CFrame.identity
if stance == Stances.Proning then
local rightFlip = CFrame.Angles(math.rad(0), math.rad(0), math.rad(90))
local leftFlip = CFrame.Angles(math.rad(0), math.rad(0), math.rad(-90))
local neckFlip = CFrame.Angles(math.rad(-90), math.rad(0), math.rad(0))
neckOffset *= neckFlip
rightShoulderOffset *= rightFlip
leftShoulderOffset *= leftFlip
end
local value = 0
if itemData and itemData.RightArmMovement then
value = 1
end
rightShoulderOffset = CFrame.identity:Lerp(rightShoulderOffset, value)
leftShoulderOffset = CFrame.identity:Lerp(leftShoulderOffset, value)
local neckCFrame:CFrame = baseNeckCFrame * neckOffset
local rightShoulderCFrame:CFrame = baseRightShoulderCFrame * rightShoulderOffset
local leftShoulderCFrame:CFrame = baseLeftShoulderCFrame * leftShoulderOffset
if itemData and item then
local baseTool6DC0CFrame:CFrame = itemData.GripC0 or CFrame.identity
local baseTool6DC1CFrame:CFrame = itemData.GripC1 or CFrame.identity
local tool6D:Motor6D? = self.Character:FindFirstChild("Tool6D", true)
if tool6D then
local rX, rY, rZ = neckOffset:ToOrientation()
local rotation = CFrame.Angles(-rX, 0, 0)
local degreesRotation = math.deg(rX)
local value = degreesRotation / 90
local tool6DCFrame = rotation
if workspace.Value.Value then
tool6D.C0 = rotation
end
end
end
self.Neck.C0 = neckCFrame
self.RightShoulder.C0 = rightShoulderCFrame
self.LeftShoulder.C0 = leftShoulderCFrame
I’m still having this issue, I got reference points when looking up and down and lerping based on the percentage of how far up/down you’re looking and it kind of works but the in between values (45 degrees) offset slightly, if anyone could point me to some math formula that I could use please help.
I have no experience in first person gun mechanics whatsoever. But why not just set the right arm be the parent of the gun? The gun will stay in place at the spot you want it to be, it’ll stick to the arm at the same position no matter what. I think it’d work because the arm is working as you want it to already. I dunno, that’s just my idea.
That couldn’t work because the animations were made to be welded to the torso and also I decided to weld it to the torso so the gun’s position wouldn’t change when the arms position changed, but I found a solution finally. I feel dumb now but I’ll explain it in case anyone needs this for help or something:
(keep in mind you’re responsible for applying this to your own game, and a lot of the code is specific to my game)
function Object:UpdateMotors()
local stance = self:GetHumanoidState("Stance")
local itemData, item = self:GetCurrentItemData()
local baseNeckCFrame:CFrame = self.BaseNeck
local baseRightShoulderCFrame:CFrame = self.BaseRightShoulder
local baseLeftShoulderCFrame:CFrame = self.BaseLeftShoulder
local neckOffset = self:GetHumanoidState("N") or CFrame.identity
local rightShoulderOffset = self:GetHumanoidState("RS") or CFrame.identity
local leftShoulderOffset = self:GetHumanoidState("LS") or CFrame.identity
if stance == Stances.Proning then
local rightFlip = CFrame.Angles(math.rad(0), math.rad(0), math.rad(90))
local leftFlip = CFrame.Angles(math.rad(0), math.rad(0), math.rad(-90))
local neckFlip = CFrame.Angles(math.rad(-90), math.rad(0), math.rad(0))
neckOffset *= neckFlip
rightShoulderOffset *= rightFlip
leftShoulderOffset *= leftFlip
end
local value = 0
if itemData and itemData.RightArmMovement then
value = 1
end
rightShoulderOffset = CFrame.identity:Lerp(rightShoulderOffset, value)
leftShoulderOffset = CFrame.identity:Lerp(leftShoulderOffset, value)
local neckCFrame:CFrame = baseNeckCFrame * neckOffset
local rightShoulderCFrame:CFrame = baseRightShoulderCFrame * rightShoulderOffset
local leftShoulderCFrame:CFrame = baseLeftShoulderCFrame * leftShoulderOffset
if itemData and item then
local baseTool6DC0CFrame:CFrame = itemData.GripC0 or CFrame.identity
local baseTool6DC1CFrame:CFrame = itemData.GripC1 or CFrame.identity
local tool6D:Motor6D? = self.Character:FindFirstChild("Tool6D", true)
if tool6D then
local rX, rY, rZ = (neckOffset):ToOrientation()
local rotation = CFrame.Angles(-rX, 0, 0) --* CFrame.new(baseNeckCFrame.Position)
local degreex = math.deg(rX)
local value = degreex / 90 * -1
local torso:BasePart = self.Character:FindFirstChild("Torso")
local rightArm:BasePart = self.Character:FindFirstChild("Right Arm")
tool6D.C0 = rightShoulderCFrame * baseRightShoulderCFrame:Inverse() --CFrame.Angles(0, math.rad(-90), 0) * CFrame.new(-1, -0.5, 0)
end
end
self.Neck.C0 = neckCFrame
self.RightShoulder.C0 = rightShoulderCFrame
self.LeftShoulder.C0 = leftShoulderCFrame
end
Okay so, I want the gun (Tool6D) to be relative to the right arm. What I did was take the rightShoulderOffset (Torso > Right Shoulder > Starting C0 property) and inversed it, and then added it to the rotation CFrame. The rotation CFrame (rightShoulderOffset) is just a rotation CFrame with a rotation on one axis.
This took me a long while to figure out and it seems obvious now but just incase anyone ever decides to do this and runs into the same issue, here you go.