[A little long]Creating FPS game system, is this a good way to load in Viewmodels?

Hi, making an FPS game, and I’d like be efficient with Client loading objects, so in short I’m simply attempting to make it so that when a viewmodel is cloned to a player, it is stored away on death and retrieved when desired.

I have a great use of CollectionService in my script which is still new to me, it seems very handy but I just wanted to make sure that this is a good use for it

Script (necessarily) does this:

  • Check its own attribute if its true or not, basically a debounce somewhat
  • If its false, clone the tagged viewmodel, tag it, set it up, and put it into the server folder
  • if its true, get the newly tagged viewmodel and put it into the server folder
  • after this check, enable all child scripts
  • on death, put away the cloned viewmodel in replicatedstorage and disable all scripts
-- Services
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local CollectionService = game:GetService('CollectionService')
local Players = game:GetService('Players')

-- Variables
local Plr = Players.LocalPlayer
local Character = Plr.Character or Plr.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChildOfClass('Humanoid')

local TargetModel = nil
local ViewModel = nil

-- Functions
function SetAllScriptsEnabledTo(Value : boolean)
	for i, v in pairs(script:GetChildren()) do
		if v:IsA('LocalScript') then
			v.Enabled = Value
		end
	end
	if Value == false then script.Enabled = false end
end

function ExitSequence(DesiredModel : Model)
	
	DesiredModel.Parent = ReplicatedStorage
	SetAllScriptsEnabledTo(false)
	
end

function EnterViewmodel(DesiredModel : Model)
	
	DesiredModel.Parent = CollectionService:GetTagged("Viewmodel_Target")[1] -- Folder to store Viewmodel for client in workspace
	
end

function CreateAndSetupViewmodel(Viewmodel : Model) print('viewmodel created')
	
	Viewmodel = TargetModel:Clone()
	CollectionService:AddTag(Viewmodel, "Loaded_Uzi_Viewmodel")

	Viewmodel:FindFirstChildOfClass('BodyColors').LeftArmColor3 = Character:FindFirstChildOfClass('BodyColors').LeftArmColor3
	Viewmodel:FindFirstChildOfClass('BodyColors').RightArmColor3 = Character:FindFirstChildOfClass('BodyColors').RightArmColor3
	Viewmodel:FindFirstChildOfClass('Shirt').ShirtTemplate = Character:FindFirstChildOfClass('Shirt').ShirtTemplate
	
	EnterViewmodel(Viewmodel)
	
end

-- Initialization
if script:GetAttribute("AlreadyClonedModel") == false then
	
	TargetModel = CollectionService:GetTagged("Uzi_Viewmodel")[1]
	if TargetModel == nil then TargetModel = CollectionService:GetInstanceAddedSignal("Uzi_Viewmodel"):Wait() end

	script:SetAttribute("AlreadyClonedModel", true)
	
	CreateAndSetupViewmodel(ViewModel)

elseif script:GetAttribute("AlreadyClonedModel") == true then
	
	ViewModel = CollectionService:GetTagged("Loaded_Uzi_Viewmodel")[1]
	EnterViewmodel(ViewModel)

end

SetAllScriptsEnabledTo(true)

-- On Death Reset
Humanoid.Died:Connect(function()
	ExitSequence(CollectionService:GetTagged("Loaded_Uzi_Viewmodel")[1])
end)

To clarify potential questions:

  • This is a script in StarterPlayerScripts, it is disabled by default, and enabled by another script
  • This script will have multiple scripts under it, for calibrating the viewmodel to camera, getting client input, and playing viewmodel animations, etc

Is this a good way to avoid constantly cloning the same viewmodel and loading its animations over and over again?
Is this even necessary/beneficial?

1 Like