How do people attach a viewmodel to the camera so smoothly?

Trying to attach the viewmodel to the player’s camera, and most gun kits and games have it just perfectly on the camera?

im wondering how they do this as im just setting the pivot of the viewmodel to the currentcam’s cframe which isnt working too well

Code that i forgot to add

-- Wait()
repeat task.wait() until game:GetService("Players").LocalPlayer.Character

-- Variables
local Player = game:GetService("Players")["LocalPlayer"]
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local HoldAnim = Instance.new("Animation"); HoldAnim.AnimationId = "rbxassetid://10469949936"
local ShootAnim = nil

local ViewModel = game.ReplicatedStorage.AkViewmodel:Clone(); ViewModel.Parent = game.Workspace.Camera
local Animator = ViewModel:WaitForChild('Humanoid').Animator

local Locked = false
local LockedConnection = nil

-- Functions
local function LockToCamera()
	if Locked then return end
	
	Locked = true
	coroutine.resume(coroutine.create(function()
		local S, E = pcall(function()
			ViewModel:WaitForChild("CameraBone")

			LockedConnection = RunService.Heartbeat:Connect(function()
				ViewModel:PivotTo(workspace.CurrentCamera)
			end)
		end)
	end))
end

local function Unlock()
	if Locked then
		Locked = false
		LockedConnection:Disconnect()
	end
end

-- Main
ViewModel.CameraBone.Transparency = 1

Animator:LoadAnimation(HoldAnim):Play()
LockToCamera()
1 Like

you could try doing that inside of a function connected to game.RunService.Heartbeat

Most if not all fps games set their viewmodels cframe to the camera’s cframe every frame, so try setting your’s in a RenderStepped event or use BindToRenderStep

This is what i was orignially doing, but it still lags behind when turning and moving

Tried this and for me it had the same result as .Heartbeat

Not sure what is wrong without any code

But with renderstep it should be smooth like this below :point_down:

1 Like

Mb, ill add the current code in

idk checked it out and mine just lags behind when i move to fast or something

are you doing it on clientside? it shouldnt lag behind

you could handle it on a local script for the localplayer, then fire a remote event with the cframe to tell the server to tell the other clients where that player is facing to update it on their clientsided

yeah, its all in a local script

Noting this down to do later

Is this code you posted the only code you have? because I noticed that it will error

Try these following changes

local function LockToCamera()
	if Locked then return end
	
	Locked = true
	coroutine.resume(coroutine.create(function()
-		local S, E = pcall(function()
			ViewModel:WaitForChild("CameraBone")

-			LockedConnection = RunService.Heartbeat:Connect(function()
+			LockedConnection = RunService.RenderStepped:Connect(function()

-				ViewModel:PivotTo(workspace.CurrentCamera)
+				ViewModel:PivotTo(workspace.CurrentCamera.CFrame)

-			end)
		end)
	end))
end
1 Like

had to remake the script due to some changes, forgot to change the pivot to .CFrame here

This did work, it now sticks on the camera :+1:

This is exactly why you shouldn’t use pcall in this manner.

The following is for the thread’s poster.

local CameraBone = ViewModel:WaitForChild("CameraBone") --This should be moved outside of the function (it only needs to be waited for once).

local function LockToCamera()
	if Locked then return end
	Locked = true
	--The coroutine is completely unnecessary, 'Heartbeat' will not yield the current thread's execution.
	LockedConnection = RunService.Heartbeat:Connect(function()
		ViewModel:PivotTo(workspace.CurrentCamera.CFrame)
	end)
end

--Unlock function here.

-- Main
CameraBone.Transparency = 1 --Earlier 'WaitForChild' simplifies this reference.
Animator:LoadAnimation(HoldAnim):Play()
LockToCamera()
2 Likes