How to make AimOffset for viewmodel aiming in?

ive been stuck on this for a while

-this is what I have

-this is what im trying to achieve

theres an aimpart on the gun; when aiming in , theres an aiming offset variable which aligns the gun sight to the middle of the players screen (by moving the viewmodel)

i have an attachment on the gun called aimAttach

right now, my offset variable moves with the gun, so you can’t see any movements or animations on the gun, since the viewmodel is orientating forwards at all times

on the bottom clip, the guns animations or movements is not limited when aiming

i’d like it to act like the bottom clip where the offset variable is counter acting or not affected by the guns movement; how could this be done?

this is the code i have, its really messy because ive been trying lots of different things

		local lerpAlpha = TweenService:GetValue(indexAim, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
		
		local AIMCFRAME = CFrame.new()
		
		
		if GunEquipped then
			
			offsetTest = (offsetTest or CFrame.new()):Lerp(ViewModel.PrimaryPart.CFrame:ToObjectSpace(GunEquipped:FindFirstChild("AimAttach").WorldCFrame * CustomViewModelPosition):Inverse(), indexAim)
			AIMCFRAME = AIMCFRAME * AIMCFRAME:Lerp( offsetTest  , lerpAlpha)
			
		end
		
		
		
		local CF = workspace.CurrentCamera.CFrame * OldCamCF:Inverse()
		
		
		
		ViewModelRoot.CFrame =  (CF * AIMCFRAME  *  CustomViewModelPosition)
1 Like

i found a manual tedious way to get the result of what im trying to do, but i’d like to try find an automatic or easier process

with the old scripts, i aim in and print out this cframe

ViewModel.PrimaryPart.CFrame:ToObjectSpace(GunEquipped:FindFirstChild("AimAttach").WorldCFrame

this gives the offset needed for that gun

		local a1 = CFrame.new( 0.612272203, 0.914476871, -0.196085453, 0.999998748, -0.00152445957, 0.00055353716, 0.00152747286, 0.999983907, -0.00548495352, -0.000545158982, 0.00548578799, 0.999984741) * CFrame.new(-CustomViewModelPosition.X, -CustomViewModelPosition.Y, -CustomViewModelPosition.Z):Inverse()
		
		AIMCFRAME = CFrame.new():Lerp( a1:Inverse(), lerpAlpha )
		
		--ViewModelRoot.CFrame =  CF * AIMCFRAME  *  CustomViewModelPosition
		ViewModelRoot.CFrame =  (CF * AIMCFRAME)  *  CustomViewModelPosition

this gives the result i want

but this is tedious because i have to manually repeat that process to get the offset if the model changes, if the idle for the model changes, or if im making a new gun

Is there anyway to automate or ease this process?


i tried walking the steps back

		local CF = workspace.CurrentCamera.CFrame * OldCamCF:Inverse()
		
		local a1 = CFrame.new( 0.612272203, 0.914476871, -0.196085453, 0.999998748, -0.00152445957, 0.00055353716, 0.00152747286, 0.999983907, -0.00548495352, -0.000545158982, 0.00548578799, 0.999984741) * CFrame.new(-CustomViewModelPosition.X, -CustomViewModelPosition.Y, -CustomViewModelPosition.Z):Inverse()
		
		AIMCFRAME = CFrame.new():Lerp( a1:Inverse(), lerpAlpha )
		
		--ViewModelRoot.CFrame =  CF * AIMCFRAME  *  CustomViewModelPosition
		ViewModelRoot.CFrame =  (CF * AIMCFRAME)  *  CustomViewModelPosition
			ViewModel.HumanoidRootPart.RootJoint.Transform = LocalPlayer.Character.HumanoidRootPart.RootJoint.Transform

it gives this result which kills all rotation in the animation which is bad

im not sure if the only way to do what im trying to do is through that manual process of going in and out of studio getting the offset cframe for every new gun; any help appreciated alot if theres a way to automate this

	-- Get the time to aim
	local aiming_time: number = Global.ToolHandler.config.AimingTime -- the time it takes to aim, example 0.1
	local aim: number = Global.ToolHandler.aim.Position -- basically a value from 0-1, 0 is not aiming, 1 is fully aiming
	
	-- Viewmodels offset cframe
	local viewmodel_offset: CFrame = Global.ToolHandler.config.ViewmodelOffset
	
	-- Update aim cframe
	if aiming_time then
		
		-- Aim cframe
		local offset: CFrame = self.viewmodel.HumanoidRootPart.CFrame * CFrame.new(0, 1.5, 0)
		local target: CFrame = self.tool_model.PrimaryPart.AimPoint.WorldCFrame * viewmodel_offset
		self.aim_point = self.aim_point:Lerp(offset:ToObjectSpace(target):Inverse(), 0.5)
		self.aim_cframe = CFrame.new():Lerp(self.aim_point, aim)
	end
	
	-- Update viewmodel cframe
	self.viewmodel:PivotTo(
		Global.camera.CFrame
		* self.aim_cframe
		* viewmodel_offset
	)

this is what im using for mine

viewmodel is the model of the viewmodel.
tool_model is the gun model inside of the viewmodel
AimPoint is a attachment inside of the toolmodels primarypart

1 Like

hi , thanks for replying

i tried to remake yours, i may have done something wrong

		local offset10 = ViewModel.HumanoidRootPart.CFrame
		local target10 = GunEquipped.AimAttach.WorldCFrame * CustomViewModelPosition
		 aimpoint10 = CFrame.new():Lerp(offset10:ToObjectSpace(target10):Inverse(), lerpAlpha)
		local cf10 = CFrame.new():Lerp(aimpoint10, lerpAlpha)
		
		
		
		--ViewModelRoot.CFrame =  CF * AIMCFRAME  *  CustomViewModelPosition
		ViewModelRoot.CFrame =  (CF * cf10)  *  CustomViewModelPosition

it gave the same result as the second clip from my last reply where the rotation is cancelled; is that how yours acts?

i’d like it to act how it does in the first clip from my last reply; instead of the offset moving with gun, it stays in one position so you can fully see the guns animation; but to get that offset, i have to go into studio and print out a cframe. im trying to see if theres an automatic way to get that offset cframe through script, i dont think its possible though

also your surfaceprojection module is really cool

the gun im using for mine has minimal rotation, i think it works but it could just be my eyes messing with me, idk

Have you tried moving the attachment point out of the gun model ? like moving it into the viewmodels primarypart and fixing it cframe to match what it would be if it was parented to the gun model (i have no idea if this would work or not, just the first idea that came to mind)

if youre able to print the value out, wouldnt you be able to use that value in the script automaticly ?

when you equip a gun, you could try to “simulate” a aim and get its offset value. Not actually making the viewmodel aim, but just doing the math for it so you can get the value

sorry if im bad at explaining, i hope thats somewhat understandable

1 Like

thanks for replying,

to get that value, i have to print out the cframe while aiming

the second idea might work but, would the offsetCframe be wrong if an animation was playing or etc? - an equip animation will play so

maybe i can try get it to simulate being completely still and aiming, im not sure how i’d do it though

the first idea might work too but do the cframes act differently under different parents? i think that’d be a better solution if there’s a way to get it to be in the same position; it currently moves when i put the aimattach into the viewmodel

everything was understandable no worries; im struggling to explain this too

You could just discard the rotation by just using the position, the code could be

aimpoint10 = CFrame.new():Lerp(offset10:ToObjectSpace(target10):Inverse(), lerpAlpha)
local cf10 = CFrame.new():Lerp(CFrame.new(aimpoint10.Position), lerpAlpha
2 Likes

why the hell are you type checking everything?? all of ur variables inferr the type

Besides all the animation stuff you guys are talking about,
The main difference I see in this view model from the one you showed is that the one you showed changed the cameras field of view to like 40 or something really zoomed in.
I think it would look better with lower fov

1 Like

its habit
leave me alone :sob:

1 Like


the first is trying that code; i think since the cframes attached to the moving part on the gun, you cant see the gun moving back/forwards. im trying to get it to act like the second clip

I dont know if this makes sense but,

is there some maths to make the aimattach on the gun model be in the same place on the viewmodel aimattach based on the cframe?

The way i do my aiming is viewmodel_Value.Torso.CFrame:Inverse() * viewmodel_Value.AimPart.Position

1 Like

hi, im trying to a different way for the offset aim value

im trying @eclipse6273094’s idea

this is what I have right now, theres an aimAttach in the viewmodel and one in the gun

im trying to get the viewmodel’s aimattach to be in the same place as the real guns aimattach but; im trying to figure out how to do this because theyre under different parents and dont act the same with positions
its slightly off right now and idk how to get it to be closer

local gun1 = workspace.aeroactual.ak47.AimAttach ;  local vm1 = workspace.Camera.ViewModel.HumanoidRootPart.AimAttach ; vm1.CFrame = CFrame.new(0,0,0)  ; local test = gun1.CFrame:ToObjectSpace(vm1.CFrame) ; local viewmodelPos = CFrame.new(-.3,-1.1,0) ; print(test); vm1.CFrame = test:Inverse()

have you tried setting it’s WorldCframe to the gun’s aimattach’s WorldCFrame