So im making my own module for my fps games to make viewmodels the issue i have is i do a for i `v in pairs to search if the character has body colors and a shirt to then parent to the vm the issue is sometimes it doesnt parent at all ik it may be the script not detecting the char sometimes but ive tried adding a repeat wait til char ~= nil and still nothing here is the code
local Viewmodel = {}
Viewmodel.__index = Viewmodel
function Viewmodel.new(Vm:Model,Player:Player)
if not Vm:FindFirstChildWhichIsA("Humanoid") then
warn("Viewmodel does not have a humanoid")
return
elseif Vm == nil or Player == nil then
warn("Viewmodel or Player is nil ")
print(Viewmodel,Player)
return
end
local NewVm = {}
setmetatable(NewVm,Viewmodel)
NewVm.Viewmodel = Vm:Clone()
NewVm.Character = Player.Character or Player.CharacterAdded:Wait()
for i,v in pairs(NewVm.Character:GetChildren()) do
if v:IsA("BodyColors") or v:IsA("Shirt") then
v:Clone().Parent = NewVm.Viewmodel
end
end
NewVm.Viewmodel.Parent = workspace.Camera
return NewVm
end
function Viewmodel:Destroy()
self.Viewmodel:Destroy()
end
return Viewmodel
Just a couple of things I would do to solve this. I don’t know for sure, but it seems like you’re running the constructor for Viewmodel off a player added event? Instead of that, I would create a new Viewmodel each time the characters appearance is loaded like this:
-- we're guaranteeing that the character is fully loaded before creating the Viewmodel
local Players = game:GetService("Players")
local viewmodel = require(path.to.Viewmodel)
local ViewmodelModel = path.to.viewmodelModel
Players.PlayerAdded:Connect(function(player)
player.CharacterAppearanceLoaded:Connect(function(character)
Viewmodel.new(ViewmodelModel, character) -- sending the loaded character instead of the player
end)
end)
And here’s how would I change up the Viewmodel class to receive this:
local Viewmodel = {}
Viewmodel.__index = Viewmodel
function Viewmodel.new(Vm:Model, Character:Character)
local NewVm = {}
setmetatable(NewVm,Viewmodel)
NewVm.Viewmodel = Vm:Clone()
for i,v in pairs(Character:GetChildren()) do
if v:IsA("BodyColors") or v:IsA("Shirt") then
v:Clone().Parent = NewVm.Viewmodel
end
end
NewVm.Viewmodel.Parent = workspace.Camera
return NewVm
end
function Viewmodel:Destroy()
self.Viewmodel:Destroy()
end
return Viewmodel
Sometimes a player might join before the PlayerAdded connection is set. To fix this, you have to make sure every player that is already in the game gets a Viewmodel too.
-- Services --
local RP = game:GetService("ReplicatedStorage")
-- Folders --
local Modules = RP:WaitForChild("Modules")
local Assets = RP:WaitForChild("Assets")
local ViewmodelFolder = Assets.Viewmodel
-- Player --
local Players = game:GetService("Players")
local PlayerData = {
Viewmodel = nil
}
-- viewmodel --
local ViewmodelModule = require(Modules.ViewmodelLoader)
local ViewmodelModel = ViewmodelFolder.VMArms
-- Player Code --
for _, player in Players:GetPlayers() do
local character = player.Character or player.CharacterAppearanceLoaded:Wait()
ViewmodelModel.new(ViewmodelModel, ViewmodelModule)
end
Players.PlayerAdded:Connect(function(player)
print(1)
player.CharacterAppearanceLoaded:Connect(function(character)
print(2)
PlayerData.Viewmodel = ViewmodelModule.new(ViewmodelModel, character)
end)
end)