So I made this class system and I need feedback/debugging for it. For example, it prints 4x rather than once, and I’m not sure if the while loop is needed or if it’s just slowing it down and causing said bug. So here is the code:
gunClass
local gunClass = {}
gunClass.name = "gun"
function gunClass.shoot()
print("Shot")
end
return gunClass
swordClass
local swordClass = {}
swordClass.name = "sword"
function swordClass.swing()
print("Slashed")
end
return swordClass
PlayerScript
local player = game.Players.LocalPlayer
local guns = {"gun"}
local swords = {"sword"}
while wait(0.1) do
local character = player.Character
local tool = character and character:FindFirstChildOfClass("Tool")
if tool then
local toolName = tool.Name
if table.find(guns, toolName) then
local gunClass = require(game.ReplicatedStorage.gunClass)
tool.Activated:Connect(gunClass.shoot)
elseif table.find(swords, toolName) then
local swordClass = require(game.ReplicatedStorage.swordClass)
tool.Activated:Connect(swordClass.swing)
end
end
end
The reason why it prints 4x rather than just 1x is because it’s nested in a while loop. Try removing the while loop and just using the Activated event of the tool, like so:
PlayerScript:
local Players = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Guns = { 'gun' }
local Swords = { 'sword' }
local ToolsInBackpack = Player:WaitForChild('Backpack'):GetChildren()
for _, Tool in ipairs(ToolsInBackpack) do
if (Tool:IsA('Tool')) then
if (table.find(Guns, Tool.Name)) then
Tool.Activated:Connect(require(ReplicatedStorage:WaitForChild('gunClass')).shoot)
else if (table.find(Swords, Tool.Name)) then
Tool.Activated:Connect(require(ReplicatedStorage:WaitForChild('swordClass')).swing)
end
end
end
The ToolsInBackpack variable is defined, assuming the tools are in the Backpack. If not, change “Player:WaitForChild(‘Backpack’)” to where the tools are located. (And the tools are only located under the player’s character if they’re active.)
This function haults the thread - just like using task.wait() - until the Instance is loaded. This is especially useful if you aren’t quite sure if something will be fully loaded in when the game starts.
As for the Loop, this just goes through every tool in the backpack (defined by the ToolsInBackpack variable.) The if statement checks if it’s a tool using Type Checking, and if it’s the correct type, it continues.
And finally, the variables at the top may looks a little confusing, but I promise, they aren’t. It’s generally good coding practices to use :GetService() whenever getting any service; including workspace. It just prevents the hassle if your services get renamed or any other error caused by service-getting other ways.
One final note; this line:
local Character = Player.Character or Player.CharacterAdded:Wait()
that defines your character. If the character isn’t loaded when the script runs, it will yield the thread until it is loaded in, to prevent errors from trying to access a nonexistent character.