Offset CFrame Math

So, for my FPS Framework, I want to make automated Aim Downs Sights, i.e., without using an animation.

The issue is that I have to move the:-

  • Arms
  • Weapon
    But I can’t do that without welding the arms to the weapon, but I need the arms welded to the RootPart instead.

So I took a rig and started experimenting, and I came up with a solution!

  • An anchored part will be taken as the camera(this is just for testing purposes)
  • The RootPart will be welded to the CameraPart
  • There will be a AimPart which defines where the camera should be in order to make the player feel like they are aiming down sights.

And I came up with this

local AimPartPosition = (Camera.CFrame:inverse() * AimPart.CFrame).Position
CamWeld.C0 = CamWeld.C0 * CFrame.new(Vector3.new(-AimPartPosition.X,-AimPartPosition.Y,-AimPartPosition.Z))

Here, I get the offset of the AimPart from the CameraPart, and then reverse the position and finally apply that to the offset of RootPart to CameraPart.(The reason I put .Position is because I only want to reverse the Position and not the Rotation, just to be safe).

This works very well and I am proud I did it, but I feel like not using that extra CameraPart. I want to use RAW CFrame values instead of Motor6Ds.

This obviously wouldn’t work…

local AimPartPosition = (Camera.CFrame:inverse() * AimPart.CFrame).Position
RootPart.CFrame = Camera.CFrame:inverse() * RootPart.CFrame * CFrame.new(Vector3.new(-AimPartPosition.X,-AimPartPosition.Y,-AimPartPosition.Z))

Because

RootPart.CFrame ~= Camera.CFrame:inverse() * RootPart.CFrame

I have the offset I need to apply to the RootPart, I just do not know how.

2 Likes

What is CamWeld.C0 initially? I understand it’s for the CameraPart weld, but it’s inferred that it has an initial value since you wrote:

CamWeld.C0 = CamWeld.C0 * CFrame.new ...

And if it wasn’t simply CFrame.new(), then it wouldn’t need to be multiplied by the new CFrame made up of AimPartPosition coordinates, so I’m assuming it has a value associated with it.

CamWeld is the Motor6D which connects the RootPart to the CameraPart, or in other words CamWeld.C0 = Camera.CFrame:inverse() * RootPart.CFrame, it is the offset of the RootPart from the Camera, in CFrame

RootPart.CFrame = RootPart.CFrame * CFrame.new(Vector3.new(-AimPartPosition.X,-AimPartPosition.Y,-AimPartPosition.Z))

Well that felt like cheating I’m gonna be honest.

I realize I’m a little late to the party here, but for what it’s worth you can replace this Vector3.new bit here with -AimPartPosition

1 Like

An update on this, the vision looked a bit distorted when viewed through the camera but looked fine through the AimPart, so therefore I updated the code/formula

local Viewmodel = game.Workspace.M4A1_Viewmodel
local AimPart = Viewmodel.M4A1.GunComponents.Aim
local HRP = Viewmodel.HumanoidRootPart
local Camera = Viewmodel.CamPart

local AimPartPosition = (HRP.CFrame:inverse() * AimPart.CFrame).Position

HRP.CFrame = Camera.CFrame * CFrame.new(-AimPartPosition.X,-AimPartPosition.Y,-AimPartPosition.Z)

This is a very useful formula for people looking to make a First Person Shooter.

2 Likes