Hey, in my ROBLOX game i have this ModuleScript for a collectible called the “Byte”. It works perfectly but there is an issue. Sometimes, when the player joins, the Bytes in the game won’t load (as in, they are visible but they just don’t work, no rotation, no touch detection, nothing) or they take a LONG time to load, i can’t tell which one it is. Idk if it’s got to do with the ModuleScript itself or the way i load all the Bytes in game.
I load the Bytes via a ServerScript in ServerScriptService that fires an event called “LoadClasses” to the client when the player joins. There’s a LocalScript in StarterPlayerScripts that, when it receives the event, it iterates through all the Bytes (and other collectibles, as well as enemies, obstacles, etc.) in the game and does the .New function of their respective module for each and every collectible, obstacle, enemy, etc. in the game. Here’s the code:
Byte:
--||Service(s)
local ReplicatedStorage : ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService : TweenService = game:GetService("TweenService")
local RunService : RunService = game:GetService("RunService")
local GuiService : GuiService = game:GetService("GuiService")
local Players : Players = game:GetService("Players")
local Debris : Debris = game:GetService("Debris")
--||Variable(s)
local Player : Player = Players.LocalPlayer
local Character : Model = Player.Character or Player.CharacterAdded:Wait()
local Root : BasePart = Character:WaitForChild("HumanoidRootPart")
local Camera : Camera = workspace.CurrentCamera
local CSettings = Character:WaitForChild("Settings")
--------------------------------------
local Animations = ReplicatedStorage:WaitForChild("Animations")
local Utilities = ReplicatedStorage:WaitForChild("Utilities")
local Effects = ReplicatedStorage:WaitForChild("Effects")
local Events = ReplicatedStorage:WaitForChild("Events")
local Sounds = ReplicatedStorage:WaitForChild("Sounds")
--------------------------------------
local Functions = require(Utilities.Functions)
local Constants = require(Utilities.Constants)
--------------------------------------
local Bytes = {}
local Byte = {}
Byte.__index = Byte
--------------------------------------
local function UpdateCharacterVariables() --Do NOT remove this code, if u do, the obstacle will not work anymore once the player resets.
Character = Player.Character or Player.CharacterAdded:Wait()
Character:WaitForChild("HumanoidRootPart")
Character:WaitForChild("Settings")
--------------------------------------
Root = Character:WaitForChild("HumanoidRootPart")
CSettings = Character:WaitForChild("Settings")
end
--------------------------------------
UpdateCharacterVariables()
--------------------------------------
Player.CharacterAdded:Connect(function()
task.wait(0.1) --Delay a lil to make sure everything is loaded first
--------------------------------------
UpdateCharacterVariables()
end)
--------------------------------------
function Byte.New(Model: Model)
local self = setmetatable({}, Byte)
self._Model = Model
self._Core = Model:WaitForChild("Core")
self._Touched = false
--------------------------------------
table.insert(Bytes, self)
--------------------------------------
self._Model:GetAttributeChangedSignal("CollectedElectron"):Connect(function()
if self._Model:GetAttribute("CollectedElectron") then
self:Collect(Player)
end
end)
--------------------------------------
self._Model:GetAttributeChangedSignal("Reset"):Connect(function()
if self._Model:GetAttribute("Reset") then
self:Reset()
end
end)
--------------------------------------
return self
end
--------------------------------------
function Byte:Collect(Player: Player)
local UIEffects : ScreenGui = Player.PlayerGui:WaitForChild("Effects")
local Character : Model = Player.Character or Player.CharacterAdded:Wait()
local CSettings : Configuration = Character:WaitForChild("Settings")
local Humanoid : Humanoid = Character:WaitForChild("Humanoid")
local Root : BasePart = Character:WaitForChild("HumanoidRootPart")
local HUD = Player.PlayerGui:WaitForChild("HUD")
--------------------------------------
for _, Obj in self._Model:GetDescendants() do
if Obj ~= self._Core then
local HasEnabled = pcall(function()
local Enabled = Obj.Enabled
end)
--------------------------------------
local HasTransparency = pcall(function()
local Transparency = Obj.Transparency
end)
--------------------------------------
if HasEnabled then
Obj.Enabled = false
elseif HasTransparency and not Obj:IsA("ImageLabel") or Obj:IsA("Beam") then
Obj.Transparency = 1
end
end
end
--------------------------------------
self._Model:AddTag("NoElectron")
self._Model:AddTag("FBCollected")
self._Model:SetAttribute("Hit", true)
--------------------------------------
Events.Collectibles.Byte:FireServer()
--------------------------------------
if CSettings:GetAttribute("Propel") < Constants.PROPEL_MAX_AMOUNT then
if Constants.PROPEL_MAX_AMOUNT - CSettings:GetAttribute("Propel") >= Constants.BYTE_PROPEL_AMOUNT then
CSettings:SetAttribute("Propel", CSettings:GetAttribute("Propel") + Constants.BYTE_PROPEL_AMOUNT)
else
CSettings:SetAttribute("Propel", CSettings:GetAttribute("Propel") + (Constants.PROPEL_MAX_AMOUNT - CSettings:GetAttribute("Propel")))
end
end
--------------------------------------
local ByteEffect = script.Byte:Clone()
ByteEffect.Parent = UIEffects
--------------------------------------
Functions:PlayTween(ByteEffect, TweenInfo.new(0.25, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {Position = HUD.ByteImage.Position, ImageTransparency = 1})
--------------------------------------
Debris:AddItem(ByteEffect, 0.25)
--------------------------------------
task.spawn(function()
task.wait(0.25)
--------------------------------------
local ByteIcon = HUD.ByteImage
ByteIcon.Size = UDim2.new(0.065, 0, 0.135, 0)
--------------------------------------
Functions:PlayTween(ByteIcon, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {Size = UDim2.new(0.05, 0, 0.125, 0)})
end)
--------------------------------------
Functions:EmitParticles(Effects.Collectibles.ByteParticles, 50, self._Core, true)
--------------------------------------
Sounds.Collectibles.Byte.PlaybackSpeed = math.random(9, 10)/10
Sounds.Collectibles.Byte:Play()
end
--------------------------------------
function Byte:Reset()
self._Touched = false
--------------------------------------
self._Model:SetAttribute("Reset", false)
self._Model:SetAttribute("Hit", false)
self._Model:SetAttribute("CollectedElectron", false)
--------------------------------------
self._Model:RemoveTag("FBCollected")
--------------------------------------
if not self._Model.Parent:IsA("Model") and not self._Model.Parent:HasTag("Collectible") and self._Model.Parent.Name ~= "Megabyte" then
self._Model:RemoveTag("NoElectron")
end
--------------------------------------
for _, Obj in self._Model:GetDescendants() do
if Obj ~= self._Core then
local HasEnabled = pcall(function()
local Enabled = Obj.Enabled
end)
--------------------------------------
local HasTransparency = pcall(function()
local Transparency = Obj.Transparency
end)
--------------------------------------
if HasEnabled then
Obj.Enabled = true
elseif HasTransparency and not Obj:IsA("ImageLabel") or Obj:IsA("Beam") then
Obj.Transparency = Obj:GetAttribute("Transparency")
end
end
end
end
--------------------------------------
local Params = OverlapParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
--------------------------------------
RunService.Heartbeat:Connect(function(DT)
for i = #Bytes, 1, -1 do
local Obj = Bytes[i]
--------------------------------------
if Obj._Touched or Obj._Model:GetAttribute("Hit") or Obj._Model:GetAttribute("CollectedElectron") or Obj._Model:HasTag("FBCollected") then --If the Byte is collected, don't run Hitbox checks.
continue
end
--------------------------------------
local Distance = (Obj._Core.Position - Root.Position).Magnitude
--------------------------------------
if Distance < Constants.CLASS_DISTANCE_CHECK then
if not CSettings:GetAttribute("ChronalHalt") then
Obj._Core.CFrame *= CFrame.Angles(0, 0, math.rad(45 * DT))
end
--------------------------------------
local CollectConditions = not Obj._Touched and not Obj._Model:GetAttribute("CollectedElectron") and not Obj._Model:HasTag("FBCollected")
--------------------------------------
if CollectConditions then
Params.FilterDescendantsInstances = {Obj._Model}
Params.RespectCanCollide = false
--------------------------------------
local Parts = workspace:GetPartBoundsInBox(Obj._Core.CFrame, Obj._Core.Size, Params)
--------------------------------------
for _, Part : BasePart in Parts do
local PLR = Players:GetPlayerFromCharacter(Part:FindFirstAncestorOfClass("Model"))
--------------------------------------
if PLR and PLR == Player then
Obj._Touched = true
--------------------------------------
Obj:Collect(Player)
--------------------------------------
break
end
end
end
end
end
end)
--------------------------------------
return Byte
Local Script that requires everything:
--||Service(s)
local ReplicatedStorage : ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService : CollectionService = game:GetService("CollectionService")
local RunService : RunService = game:GetService("RunService")
local GuiService : GuiService = game:GetService("GuiService")
local Players : Players = game:GetService("Players")
--||Variable(s)
local Player : Player = Players.LocalPlayer
local Camera : Camera = workspace.CurrentCamera
local Controls = require(Player.PlayerScripts:WaitForChild("PlayerModule")):GetControls()
local Classes = ReplicatedStorage:WaitForChild("Classes")
local Demo = workspace:WaitForChild("Demo")
--------------------------------------
local EffectsUI = Player.PlayerGui:WaitForChild("Effects")
--------------------------------------
local Events = ReplicatedStorage:WaitForChild("Events")
--||Function(s)
local function PlayerAdded(PLR: Player)
for _, Folder in CollectionService:GetTagged("ClassFolder") do
local Class = require(Classes:FindFirstChild(Folder.Parent.Name):FindFirstChild(Folder:GetAttribute("Class")))
--------------------------------------
for _, Obj in Folder:GetChildren() do
Class.New(Obj)
end
end
end
--||Connection(s)
Events.Player.LoadClasses.OnClientEvent:Connect(PlayerAdded)
Server Script that fires the event:
--||Service(s)
local ReplicatedStorage : ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService : CollectionService = game:GetService("CollectionService")
local RunService : RunService = game:GetService("RunService")
local GuiService : GuiService = game:GetService("GuiService")
local Players : Players = game:GetService("Players")
--||Variable(s)
local Animations = ReplicatedStorage:WaitForChild("Animations")
local Events = ReplicatedStorage:WaitForChild("Events")
--||Function(s)
local function PlayerAdded(Player: Player)
task.spawn(function() --Make all invisible objects invisible.
local InvisibleAttempts = 0
--------------------------------------
repeat
InvisibleAttempts += 1
--------------------------------------
for _, InvisibleObj in CollectionService:GetTagged("Invisible") do
if InvisibleObj:IsA("Beam") or InvisibleObj:IsA("Attachment") or InvisibleObj:IsA("SurfaceGui") then
InvisibleObj:Destroy()
elseif InvisibleObj:IsA("BasePart") then
InvisibleObj.Transparency = 1
end
end
--------------------------------------
task.wait(0.25)
until InvisibleAttempts == 100
end)
--------------------------------------
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
--------------------------------------
local Settings = ReplicatedStorage:WaitForChild("PlayerSettings"):Clone()
Settings.Name = "Settings"
Settings.Parent = Player
--------------------------------------
local Bytes = Instance.new("IntValue", leaderstats)
Bytes.Name = "Bytes"
--------------------------------------
local Hexas = Instance.new("IntValue", leaderstats)
Hexas.Name = "Hexas"
--------------------------------------
local Count = Instance.new("IntValue", leaderstats)
Count.Name = "Count"
--------------------------------------
Events.Player.LoadClasses:FireClient(Player)
--------------------------------------
Player.CharacterAdded:Connect(function(Character: Model)
local Hitbox = Character:WaitForChild("HumanoidRootPart")
--------------------------------------
Hitbox.NAttachment.GUI.TextLabel.Text = "@" .. Player.DisplayName
--------------------------------------
local ARig : Model = workspace:WaitForChild("AnimationRig")
local AAnimator : Animator = ARig.Humanoid.Animator
--------------------------------------
for _, Animation in Animations.Player:GetChildren() do
local Anim = AAnimator:LoadAnimation(Animation)
--------------------------------------
Anim:Play()
end
end)
end
--||Connection(s)
Players.PlayerAdded:Connect(PlayerAdded)
Help would be greatly appreciated!