How to make my gun face in the direction of the camera?

You don’t need to know the CFrame. :slight_smile:
If you’re referring to the “ViewModelCF” variable in that script, it just sets where you’d like the Pistol to sit on the screen.

You should use a separate script that handles ViewModels; (this script sits in “ReplicatedFirst”) - but it can also be in StarterPlayerScripts.

ViewModel Example script: (note that this is very messy & rushed.)

--[[ Note: THIS doesn't copy animations of the character or effects of the tool equipped, such as firing effects. ]]--
--[[ Variables ]]--
local ViewModel = nil -- The ViewModel itself.
local ViewModelCF = CFrame.new(.5,-1,-2) -- Same meaning script as above. Where you'd like the ViewModel to sit on the screen.
local Player = game:GetService("Players").LocalPlayer
local PhysicsService = game:GetService("PhysicsService")
local Character = nil
local Connections = {} -- Event connections to cleanup everytime the player respawns.
--[[ Functions ]]--
function HideTool()
	if (Character) then
		local Tool = Character:FindFirstChildOfClass("Tool")
		if (Tool) then
			for _,b in pairs(Tool:GetDescendants()) do -- You might also want to use this on effect instances, such as Lights, Particles, etc.
				if (b:IsA("BasePart")) then
					if (b:FindFirstChild("previousTransparencyValue")==nil) then
						local transparencyValue = Instance.new("NumberValue")
						transparencyValue.Name = "previousTransparencyValue"
						transparencyValue.Value = b.Transparency
						transparencyValue.Parent = b
					end
					b.Transparency = 1
				end
			end
		end
	end
end
function ShowTool(Tool)
	if (Character) then
		if (Tool) then
			for _,b in pairs(Tool:GetDescendants()) do -- Exact function as above but it shows the actual tool.
				if (b:IsA("BasePart")) then
					if (b:FindFirstChild("previousTransparencyValue")) then
						b.Transparency = b.previousTransparencyValue.Value
					end
				end
			end
		end
	end
end
function InitViewModel()
	for i,v in pairs(Connections) do -- Clean up previous connections.
		v:Disconnect()
		Connections[i] = nil
	end
	-- Add new connections
	table.insert(Connections,Character.ChildAdded:Connect(function(Object)
		if (Object:IsA("Tool")) then
			ViewModel = Instance.new("Model")
			ViewModel.Name = "ViewModel"
			ViewModel.Parent = workspace.CurrentCamera
			local newObject = Object:Clone()
			newObject.Parent = ViewModel
			if (newObject:FindFirstChild("Handle")) then
				ViewModel.PrimaryPart = newObject.Handle
				newObject = nil
			else
				warn("No handle found!")
				ViewModel:Destroy()
				newObject:Destroy()
				return
			end
			--[[ Set all of the parts in the ViewModel in to the ViewModel collisionGroup to prevent flinging ]]--
			for _,v in pairs(ViewModel:GetDescendants()) do
				if (v:IsA("BasePart")) then -- "BasePart" is all part types. MeshPart/TrussPart/WedgePart/Part, etc
					PhysicsService:SetPartCollisionGroup(v, "ViewModel")
				end
			end
			--[[ Move the ViewModel in to the Camera ]]--
			ViewModel.Parent = workspace.CurrentCamera
			HideTool() -- Hide the actual tool from the client.
		end
	end))
	table.insert(Connections,Character.ChildRemoved:Connect(function(Object)
		if (Object:IsA("Tool")) then
			ShowTool(Object)
			if (ViewModel) then
				ViewModel:Destroy()
			end
			ViewModel = nil  -- Unequipped the tool, hide the ViewModel.
		end
	end))
	
end
--[[ Events ]]--
Player.CharacterAdded:Connect(function(Char)
	Character = Char
	InitViewModel()
end)
Player.CharacterRemoving:Connect(function()
	Character = nil
	if (ViewModel) then
		ViewModel:Destroy()
	end
	ViewModel = nil
end)
game["Run Service"].RenderStepped:Connect(function()
	if (ViewModel) then
		ViewModel:SetPrimaryPartCFrame(workspace.CurrentCamera.CFrame * ViewModelCF)
	end
end)

Remember to use Collision Groups to prevent flinging -
image

You should check out some other ViewModel threads - such as EgoMoose’s tutorial:

ViewModel’s imo are a little difficult to explain how to make.

I’m sorry if this is all so confusing! I hope you get your script working. :slight_smile:

2 Likes