You don’t need to know the CFrame.
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 -
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.