How to Aim Down Sights In Relation to an Animation?

Hey, this is my first time asking for help on the DevForum, so I’m not really used to doing this. But here I go:

I am trying to make the FPS element of a game I am working on. What I need is to be able to ADS my gun, however where the gun is in relation to my ViewModel’s chest is determined by an idle animation I play that I called “Revolver_Hold”

Here is the code I am currently using:

local Weld:Motor6D = ViewModel:FindFirstChild("PsuedoHrpWeld",true)
local HandlePart:BasePart = ViewModelGun.Handle
local Head:BasePart = ViewModel.Head
local RShoulder:Motor6D = ViewModel.RightUpperArm.RightShoulder
local offset:CFrame = HandlePart.CFrame:ToObjectSpace(AimPart.CFrame)

function AimDownSights(ToggleBool:boolean)
	local goal = ToggleBool and offset or CFrame.new();
	Weld.C0 = goal
end

A Little Context To This

This is a very truncated version of EgoMoose’s ADS script from his tutorial, which you can find via this link: The First Person Element Of A First Person Shooter
The only difference is that EgoMoose controls the arm placement on the Gun’s model with CFrames in his code, whereas I do this via an Idle animation instead.

Some other context is that the Motor6D “PsuedoHrpWeld” is a weld that connects the ViewModel Head to a BasePart. This is not really important, as that basePart is only used to simulate an Arm Bobbing effect on the ViewModel, and the C0 and C1 of the Motor6D is not changed or used at all in that code. Every RunService.Stepped Frame, I update this BasePart to the Player’s Camera, and the C0 and C1 offset of the weld can change the offset the ViewModel’s Head has from the BasePart, and therefore the Player’s Camera.

Also, my ViewModel is an R15 Rig with all limbs minus the LowerTorso, both legs, and HumanoidRootPart. It is parented to the game.Workspace, and my ViewModelGun is parented to the ViewModel.

Anyway, Back To The Main Problem

Here is a picture of my gun at rest:

And here is a picture of my gun when ADS’ing

What is happening is the code is moving the Revolver up to Eye level somehow with CFrames. I don’t fully understand the calculations, but I DO know that the script is doing what it should.
Now, in EgoMoose’s case, this would fully move the AimPart to the ViewModel’s Head. However, I am using Animations to determine where the revolver and the hands should be placed in relation to the Head. Therefore, the script can’t fully move the revolver to the player’s head, because I don’t think that a Part’s CFrame takes into account its CFrame Offset caused by an Animation.

A Possible Solution I Have No Idea How To Do

My current theory is that I was searching up Motor6Ds on the Roblox Docs, and apparently they have a nifty property called Motor6D.Transform, which can tell you the offset a part has from another part when an animation is running. Therefore, I believe that since I can get the offset all the limbs have from one another, I can somehow use this to calculate what exactly the offset C0 and C1 of my PsuedoHrpWeld should be so that the AimPart on my Revolver model is exactly at the Player’s Camera.

However, I have no idea how to do this, because I am not a complete expert on CFrames. So that is why I am asking for help. Or, if you think there is a solution to this problem that has literally nothing to do with my theory, then feel free to pitch that idea too. I’m all ears.

Thank you, and have a good day

Update:

I was playing around with the CFrame Values when I added this single line:

offset = (HandlePart.CFrame * offset):ToObjectSpace(Head.CFrame)

and now the ADS script result is this:

which is EXACTLY what it should be. However, if someone could explain to me WHY the heck that works, I’d much appreciate it.

2 Likes

Hello, ive had this problem too. However, i cannot reply to you right now because i do not have my computer with me, but ill try to type code in unformatted text

— if you want to make this more reliable, you can use :Lerp.

local hrp = viewmodel. — add your primary part of viewmodel
local sight = gun.sight — replace this with your gun sight position

sight.CFrame = sight.CFrame:Lerp(hrp.CFrame, 1) — 1 is to set the lerp to 100%

However, i cant tell you how your problem works, so sorry about that

The reason why it doesn’t work on the first try is because of the dreaded AnimationWeightedBlendFix. The solution is to remove ALL animations that interact with the viewmodel (or character).

You dont have to remove ALL of them, you just have to fix the priorities *

But yes, sometimes you cant fix the priorities and in that situation you cant really do much.

That is the case with me. IKControls also do not function if an animation is playing (it might be fixed now though, have not checked).

can you post the whole script please? i still can’t understand how to make it work

Sure, I’m sorry for not responding sooner.

function GetOffset():CFrame
	local VM = ViewModel:Clone()
	VM.Parent = game.Workspace
	--VM.UpperTorso.Anchored = true
	for i,v:AnimationTrack in pairs(VM.Humanoid.Animator:GetPlayingAnimationTracks()) do
		v:Stop()
	end
	local VMGun = VM:FindFirstChild(ViewModelGun.Name)
	local HoldTrack:AnimationTrack = VM.Humanoid.Animator:LoadAnimation(script.Parent.Parent.Anims.Hold)
	HoldTrack:Play(0)
	for i,v:BasePart in pairs(VM:GetDescendants()) do
		if v:IsA("BasePart") then
			v.Transparency = 1
		end
	end
	
	wait(0.1)
	local offset:CFrame = VMGun.Handle.CFrame:ToObjectSpace(VMGun:FindFirstChild("AimPart",true).CFrame)
	offset = (VMGun.Handle.CFrame * offset):ToObjectSpace(VM.Head.CFrame)
	VM:Destroy()
	return offset
end

To explain this, I have a 1st person ViewModel of the player. When the player equips a new gun, right after the gun model loads, I say

local offset = GetOffset()

I copy the player’s viewmodel, stop all the animations on it EXCEPT for the holding animation. Then, I get the distance going from the gun’s AimPart → the gun’s Handle, then the gun’s Handle → the ViewModel’s head

When I want to aim the gun, I have the CFrame offset, and I apply it to a Weld that connects the ViewModel to the player’s Camera. I apply the offset to the Weld.C0

Hope this helped, and sorry again for the late reply!

Thank you for replying! Don’t worry about replying late, because late is still better than never :slight_smile:

Hey I know I’m late but i had the same problem and it was cuz i used attachments parented to the primary part of the model, and so if i play and animation on the viewmodel’s arms it wont move the attachment cuz the attachment’s parent is the primary part which Isn’t moved in the animation. Just parent the attachment to something that is being moved in the animation.