Aim-down-sights by offsetting main viewmodel part

Essentially, I have a part that represents where your camera should be looking when aimed down. But because this “aim part” isn’t the base part of the viewmodel, it wouldn’t drag everything else (like the arms & gun) with it. If I were to move it, it would only move by itself. So, I need a method to move this aim part to the camera, but by offseting the main viewmodel part, so that everything else follows it.

Here’s a picture if it makes my goal clearer.

Sorry if this was explained poorly, I can elaborate if requested; explaining stuff concisely is not my strong suit.

2 Likes

I’d get the CFrame offset between the base/camera and the aim part. Then, I’d multiply the base’s CFrame by the offset.

local AimOffset = Base.CFrame * AimPart.CFrame:Inverse()
-- or
local AimOffset = Camera.CFrame * AimPart.CFrame:Inverse()

Keep in mind that you’d have to also update the base for each step to keep the aim consistent. Also, this is just some simple code to get the aim part in position with the base’s (or camera’s) CFrame. I’d advise using TweenService or lerping the CFrame to get a smooth transition for aiming.

I tried this before, and it didn’t work. Here is what my code looks like.

local AimPartOffset =  LocalPlayerData.Camera.CFrame * ViewmodelAimPart.CFrame:Inverse()
self.ViewmodelOffset = AimPartOffset

This happens every render-step as you said, but it doesn’t seem to work. It just displaces the viewmodel far away, inexplicably.

So far that I can’t really show it. In this screenshot the viewmodel teleports about 1500 studs away after running the aiming code.

Before/After:


(p.s.: the particles in the after photo are from me shooting the gun)

It would help to see further code where you position the base relative to the camera. If you’re doing something like

base.CFrame = Camera.CFrame * AimPartOffset

then you have the flaw that each time this occurs the offset is changing because the first time, the base part will be pushed back so that there no longer is an offset between the aim part and camera, however the next time this occurs the calculated offset will be something like the identity cframe, so then the base part will be set back to the cameras position, repeating the loop. I’m not sure how this would result in the gun model being 1500 studs away but I think providing that area of your code will help.

Try calculating the aim offset by doing the other suggestuon suggested by DesiredFlamingFire, and see if that works.

local AimPartOffset =  Base.CFrame * ViewmodelAimPart.CFrame:Inverse()

Here is the code that positions the viewmodel every renderstep.

            self.RepositionViewmodelConnection = RenderStepped:Connect(function()
                local NewCFrame = Camera.CFrame * self.ViewmodelOffset

                Viewmodel:SetPrimaryPartCFrame(NewCFrame)
            end)

self.ViewmodelOffset is never changed except for when aiming down sights as shown in the previous code samples.

Here’s the result of using the Base’s CFrame instead. It changed every time I right clicked and ran the function.

Is ViewmodelOffset a Vector3 value? I had the same problem before caused by this. Perhaps you may want to change it to a CFrame value instead.

ViewmodelOffset is a CFrame value.