So I made a viewmodel arms script for tools, works pretty nice.
How I coded it
It clones a viewmodel template from ReplicatedStorage, puts the shirts, pants, and body colors of the player onto the viewmodel, use RenderStepped
to lock the viewmodel in the camera’s CFrame, clone the real tool onto the viewmodel and make the real one invisible to the client, then listen for animations and play it on the viewport.
One problem though, the actual gun/tool doesn’t follow the viewmodel.
Not really sure how to solve this. Help would be appreciated!
VIEWMODEL CODE:
local RNS = game:GetService("RunService")
local RS = game:GetService("ReplicatedStorage")
local PS = game:GetService("Players")
local PYS = game:GetService("PhysicsService")
local camera = workspace.CurrentCamera
local char: Model = script:FindFirstAncestorWhichIsA("Model") do
char.Archivable = true
end
local player: Player = PS:GetPlayerFromCharacter(char)
local hum: Humanoid = char:WaitForChild("Humanoid")
local animator: Animator = hum:WaitForChild("Animator")
local modelHum: Humanoid = nil
local modelAnimator: Animator = nil
local connections = {}
local viewmodel = nil
local loaded = {}
connections[1] = player.CharacterAppearanceLoaded:Connect(function()
viewmodel = RS.Viewmodel:Clone() do
viewmodel.Parent = camera
viewmodel.Name = "Viewmodel"
viewmodel.PrimaryPart = viewmodel:WaitForChild("Head")
modelHum = viewmodel:WaitForChild("Humanoid")
modelAnimator = modelHum:WaitForChild("Animator")
local blacklist = {"left leg", "right leg"}
for _,v in ipairs(char:GetDescendants()) do
if v:IsA("Shirt") or v:IsA("Pants") or v:IsA("BodyColors") then
local clone = v:Clone() do
clone.Parent = viewmodel
end
end
end
char.Archivable = false
connections[1]:Disconnect()
end
end)
connections[2] = RNS.RenderStepped:Connect(function()
if viewmodel then
viewmodel:SetPrimaryPartCFrame(camera.CFrame)
end
end)
connections[3] = animator.AnimationPlayed:Connect(function(track)
if loaded[track] or not modelHum or not modelAnimator then
warn("i like crying")
return
end
loaded[track] = modelAnimator:LoadAnimation(track.Animation)
loaded[track]:Play()
track.Stopped:Connect(function()
loaded[track]:Stop()
loaded[track] = nil
end)
end)
connections[4] = char.DescendantAdded:Connect(function(obj)
if obj:IsA("Weld") and obj.Name == "RightGrip" then
task.wait()
for _,v in ipairs(viewmodel:GetChildren()) do
if v:IsA("Tool") or v:IsA("Weld") and v.Name == "RightGrip" then
v:Destroy()
end
end
local weld = obj:Clone() do
weld.Parent = viewmodel
end
local tool = obj.Part1.Parent:Clone() do
tool.Parent = viewmodel
weld.Part0 = viewmodel[obj.Part0.Name]
weld.Part1 = tool.Handle
end
for _,v in ipairs(obj.Part1.Parent:GetChildren()) do
if v:IsA("BasePart") then
v.LocalTransparencyModifier = 1
end
end
end
end)