Gun Aim Not Moving Smoothly

I’m currently working on a gun system and I’m trying to smoothly tween the camera to the aimpart on my gun, like so:

It sets the cameras CFrame fine and all but it instantly moves the gun to the camera so doesn’t move smoothly.


(sorry for that weird noise no idea what that is)

Heres what I’ve got

--// Aim Function
		local function aim(action, state) -- this fires from a contextactionservice bind thing
			if state == Enum.UserInputState.Begin then -- begin aiming
				viewModel.PrimaryPart = aimPart
				aiming = true
			else -- stop aiming
				viewModel.PrimaryPart = viewModelHumRoot
				aiming = false
			end
		end
-- Update Camera
        local aimPos = CFrame.new()
		local function updateViewModel() -- fires on renderstepped
			viewModel:SetPrimaryPartCFrame(camera.CFrame)
			
			if aiming then
				aimPos = aimPos:Lerp(camera.CFrame, 0.2)
			else
				aimPos = aimPos:Lerp(CFrame.new(), 0.1)
			end
		end
2 Likes

Maybe using a tween instead of a lerp would be easier and nicer, a lerp always moves at a constant speed while a Tween can have a lot of styles it will animate it to.

2 Likes

Tried that yeah, after the tween finishes though it just moves back to the original position? Is that normal?

3 Likes

I am pretty sure you can make a tween stop at its current position. Check out some tutorials maybe you’ll find something. As well does your gun have collisions on? if yes turn them off maybe it was causing some problems.

1 Like

Theres one of the properties in the TweenInfo that can be true or false. Making it true will cause it to revert to it’s old position, and making it false prevents it from doing that. You can read about it here.

1 Like

I put this together really quickly. I feel like most of this is pretty self-explanatory, but if you have any questions, let me know.

local Camera = workspace.CurrentCamera

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local AimAlpha = 0

function Lerp(Start, End, Alpha)
	return Start + (End - Start) * Alpha
end

function UpdateViewModel(DeltaTime)
	local Aiming = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2)
	
	local BaseCFrame = Camera.CFrame
	
	local NeutralOffset = CFrame.new(0.6, -0.8, -3)
	local AimOffset = CFrame.new(0, -0.2, -2)
	
	AimAlpha = Lerp(AimAlpha, Aiming and 1 or 0, 0.3)
	
	ViewModel:SetPrimaryPartCFrame(BaseCFrame * NeutralOffset:Lerp(AimOffset, AimAlpha))
end

RunService:BindToRenderStep("ViewModel", Enum.RenderPriority.Camera.Value, UpdateViewModel)

SmoothGunAimingExample.rbxl (23.0 KB)

1 Like

Sorry for the late response, what would NeutralOffset and AimOffset be? Should AimOffset be the AimPart I’m aiming to and Neutral just be the normal position when not aiming?? I don’t know what to put for NeutralOffset, this is my layout. (should it be the humrootpart)

image

Also what does this Aiming and 1 or 0 mean?

AimAlpha = Lerp(AimAlpha, Aiming and 1 or 0, 0.3)

EDIT: Also the gun doesn’t show up anymore when I equip it, it’s not in the right position

My current code:

local function updateViewModel() -- runs on renderStepped
			
			local neutralOffset = viewModelHumRoot.CFrame
			local aimOffset = aimPart.CFrame
			
			aimAlpha = lerp(aimAlpha, aiming and 1 or 0, 0.3)
			
			if humanoid.MoveDirection.Magnitude > 0 and not aiming and not reloading then 
				gunSway() 
			end
			
			viewModel:SetPrimaryPartCFrame(camera.CFrame * neutralOffset:Lerp(aimOffset, aimAlpha))
		end

NeutralOffset is the target offset applied to the camera’s CFrame when you are not aiming.

Given what I said above, you need to calculate the NeutralOffset by inverting the camera’s CFrame and multiplying by the CFrame (in world space) you want it to be set to.

Pretty much the same thing for the AimOffset as well.

It simply chooses whether to lerp towards 0 or 1 based on whether the right mouse button is pressed down or not.

AimAlpha is a value in the range [0, 1] describing the interpolation between NormalOffset and AimOffset (1 being equivalent to AimOffset and 0 being equivalent to NormalOffset).

1 Like