Straight to the point, I wrote an OOP inventory system and made a class for it called Melee, The tools for the inventory system have a FastSignal event which fires whenever they get equipped and unequipped, But for some reason when I unequip it tells me that :StopCharge() method does not exists.
The functions are connected to the events on the class constructor function:
function Melee.new(Replicated, ServerID)
local self = setmetatable(Melee.ParentClass.new(Replicated,ServerID),Melee)
self.ClassName = Melee.ClassName
-- Properties
self.Icon = 9759885209
self.ClassName = Melee.ClassName
self.Name = Melee.ClassName
-- Visuals
self.WeaponModel = nil
self.HeavyKillEffect = "Normal"
self.LightKillEffect = "Normal"
self.ClientTrail = nil
-- Stats
self.WoundType = "Swift"
self.WoundPercentage = 0
self.ChargeLength = 1.5
self.LightRecoveryDuration = 0.30
self.LightMissRecoveryDuration = 0.7
self.HeavyRecoveryDuration = 0.30
self.HeavyMissRecoveryDuration = 0.8
self.MinDamage = 6
self.MaxDamage = 15
self.HitDelayDuration = 0.1
self.Range = 4.5
self.BlockBreaking = 0
self.BlockStrength = 1
-- GUI
self.GUI = nil
-- SFX
self.SFX = {
LightHit = Assets.SFX.Weapons.Fists.LightHitSFX,
HeavyHit =Assets.SFX.Weapons.Fists.HeavyHitSFX,
LightSwing = Assets.SFX.Weapons.Fists.LightSwingSFX,
HeavySwing = Assets.SFX.Weapons.Fists.HeavySwingSFX,
Equip = Assets.SFX.Weapons.Fists.EquipSFX
}
-- ViewModel Animations/Local
self.ViewModelAnimations = {
Equip = Assets.Animations.Fists.Equip,
Idle = Assets.Animations.Fists.Idle,
Blocking = Assets.Animations.Fists.Blocking,
Charge = Assets.Animations.Fists.Charge,
Charging = Assets.Animations.Fists.Charging,
LightHit = Assets.Animations.Fists.LightHit,
HeavyHit = Assets.Animations.Fists.HeavyHit,
Shove = Assets.Animations.Fists.Shove,
Inspect = Assets.Animations.Fists.Inspect,
}
self.Equipped:Connect(function(State)
if State == true then
local playerRecord = ClientPlayerRecord:GetPlayerRecord(self.Owner)
local PlayerViewmodel = playerRecord.Assets.Player.Viewmodel
local CombatStates = playerRecord.States.Combat
-- Load all assets
PlayerViewmodel:Attach()
PlayerViewmodel:Show()
-- Loads Animations into the viewmodel
for AnimationName,Animation in pairs(self.ViewModelAnimations) do
local ClonedAnimation = Animation:Clone()
ClonedAnimation.Parent = PlayerViewmodel.Animator
PlayerViewmodel.AnimationTracks[ClonedAnimation.Name] = PlayerViewmodel.Animator:LoadAnimation(ClonedAnimation)
end
-- Reset Chargebar size
playerRecord.Assets.Player.GUI.HUD.ChargeBarOutline.Charge.Size = UDim2.fromScale(0,1)
-- Set priorities
PlayerViewmodel.AnimationTracks.Equip.Priority = Enum.AnimationPriority.Action2
PlayerViewmodel.AnimationTracks.Idle.Priority = Enum.AnimationPriority.Action
-- Transition handled by anim priorities
PlayerViewmodel.AnimationTracks.Equip:Play(0)
PlayerViewmodel.AnimationTracks.Idle:Play(0)
local function ActionHandler(Action, InputState)
local Actions = {
MouseButton1 = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Charge)
else
ClientCommands:SetCommand("MAI",Enums.MeleeData.Hit)
end
end,
MouseButton2 = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Block)
else
ClientCommands:SetCommand("MAI",Enums.MeleeData.Unblock)
end
end,
F = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Inspect)
end
end,
Q = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Shove)
end
end,
}
Actions[Action]()
end
-- Bind all actions
ContextActionService:BindAction("MouseButton1",ActionHandler, false, Enum.UserInputType.MouseButton1)
ContextActionService:BindAction("MouseButton2",ActionHandler, false, Enum.UserInputType.MouseButton2)
ContextActionService:BindAction("F",ActionHandler, false, Enum.KeyCode.F)
ContextActionService:BindAction("Q",ActionHandler, false, Enum.KeyCode.Q)
return
else
local playerRecord = ClientPlayerRecord:GetPlayerRecord(self.Owner)
local PlayerViewmodel = playerRecord.Assets.Player.Viewmodel
local CombatStates = playerRecord.States.Combat
-- Unbind all actions
ContextActionService:UnbindAction("MouseButton1")
ContextActionService:UnbindAction("MouseButton2")
ContextActionService:UnbindAction("F")
ContextActionService:UnbindAction("Q")
PlayerViewmodel:Hide()
-- Stop charge
self:StopCharge()
-- Set states
CombatStates.IsChargeWaiting = false
self:Unblock()
-- Disconnect this event since we are no longer waiting for charge
playerRecord.FastSignals.AbleToCharge:DisconnectAll()
playerRecord.FastSignals.AbleToBlock:DisconnectAll()
if playerRecord.Connections.Rbxl.HideTrailOnHitAnimationStopped then
playerRecord.Connections.Rbxl.HideTrailOnHitAnimationStopped:Disconnect()
end
-- Kill all transition coroutines
-- Stop all anims
for i,Animation in pairs(PlayerViewmodel.Animator:GetChildren()) do
Animation:Destroy()
end
for i,AnimationTrack in pairs(PlayerViewmodel.AnimationTracks) do
AnimationTrack:Stop()
PlayerViewmodel.AnimationTracks[i] = nil
end
end
end)
return self
end
Full script:
-- Services
local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local ContentProvider = game:GetService("ContentProvider")
local ContextActionService = game:GetService("ContextActionService")
local LocalPlayer = Players.LocalPlayer
local FastSignal = require(ReplicatedFirst.Packages.Chickynoid.Vendor.FastSignal)
local Enums = require(ReplicatedFirst.Packages.Chickynoid.Enums)
local BitBuffer = require(ReplicatedFirst.Packages.Chickynoid.Vendor.BitBuffer)
local Client = require(ReplicatedFirst.Packages.Chickynoid.Client)
local ClientMods = require(ReplicatedFirst.Packages.Chickynoid.Client.ClientMods)
local ClientCommands = ClientMods:GetMod("clientmods","ClientCommands")
local ClientPlayerRecord = nil
local Assets = script.Assets
local Melee = {}
Melee.ParentClass = require(script.Parent.Parent)
Melee.__index = Melee.ParentClass
Melee.ClassName = script.Name
function Melee:Charge()
end
function Melee:StopCharge()
end
function Melee:Block()
end
function Melee:Unblock()
end
function Melee:Hit()
end
function Melee.new(Replicated, ServerID)
local self = setmetatable(Melee.ParentClass.new(Replicated,ServerID),Melee)
self.ClassName = Melee.ClassName
-- Properties
self.Icon = 9759885209
self.ClassName = Melee.ClassName
self.Name = Melee.ClassName
-- Visuals
self.WeaponModel = nil
self.HeavyKillEffect = "Normal"
self.LightKillEffect = "Normal"
self.ClientTrail = nil
-- Stats
self.WoundType = "Swift"
self.WoundPercentage = 0
self.ChargeLength = 1.5
self.LightRecoveryDuration = 0.30
self.LightMissRecoveryDuration = 0.7
self.HeavyRecoveryDuration = 0.30
self.HeavyMissRecoveryDuration = 0.8
self.MinDamage = 6
self.MaxDamage = 15
self.HitDelayDuration = 0.1
self.Range = 4.5
self.BlockBreaking = 0
self.BlockStrength = 1
-- GUI
self.GUI = nil
-- SFX
self.SFX = {
LightHit = Assets.SFX.Weapons.Fists.LightHitSFX,
HeavyHit =Assets.SFX.Weapons.Fists.HeavyHitSFX,
LightSwing = Assets.SFX.Weapons.Fists.LightSwingSFX,
HeavySwing = Assets.SFX.Weapons.Fists.HeavySwingSFX,
Equip = Assets.SFX.Weapons.Fists.EquipSFX
}
-- ViewModel Animations/Local
self.ViewModelAnimations = {
Equip = Assets.Animations.Fists.Equip,
Idle = Assets.Animations.Fists.Idle,
Blocking = Assets.Animations.Fists.Blocking,
Charge = Assets.Animations.Fists.Charge,
Charging = Assets.Animations.Fists.Charging,
LightHit = Assets.Animations.Fists.LightHit,
HeavyHit = Assets.Animations.Fists.HeavyHit,
Shove = Assets.Animations.Fists.Shove,
Inspect = Assets.Animations.Fists.Inspect,
}
self.Equipped:Connect(function(State)
if State == true then
local playerRecord = ClientPlayerRecord:GetPlayerRecord(self.Owner)
local PlayerViewmodel = playerRecord.Assets.Player.Viewmodel
local CombatStates = playerRecord.States.Combat
-- Load all assets
PlayerViewmodel:Attach()
PlayerViewmodel:Show()
-- Loads Animations into the viewmodel
for AnimationName,Animation in pairs(self.ViewModelAnimations) do
local ClonedAnimation = Animation:Clone()
ClonedAnimation.Parent = PlayerViewmodel.Animator
PlayerViewmodel.AnimationTracks[ClonedAnimation.Name] = PlayerViewmodel.Animator:LoadAnimation(ClonedAnimation)
end
-- Reset Chargebar size
playerRecord.Assets.Player.GUI.HUD.ChargeBarOutline.Charge.Size = UDim2.fromScale(0,1)
-- Set priorities
PlayerViewmodel.AnimationTracks.Equip.Priority = Enum.AnimationPriority.Action2
PlayerViewmodel.AnimationTracks.Idle.Priority = Enum.AnimationPriority.Action
-- Transition handled by anim priorities
PlayerViewmodel.AnimationTracks.Equip:Play(0)
PlayerViewmodel.AnimationTracks.Idle:Play(0)
local function ActionHandler(Action, InputState)
local Actions = {
MouseButton1 = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Charge)
else
ClientCommands:SetCommand("MAI",Enums.MeleeData.Hit)
end
end,
MouseButton2 = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Block)
else
ClientCommands:SetCommand("MAI",Enums.MeleeData.Unblock)
end
end,
F = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Inspect)
end
end,
Q = function()
if InputState == Enum.UserInputState.Begin then
ClientCommands:SetCommand("MAI",Enums.MeleeData.Shove)
end
end,
}
Actions[Action]()
end
-- Bind all actions
ContextActionService:BindAction("MouseButton1",ActionHandler, false, Enum.UserInputType.MouseButton1)
ContextActionService:BindAction("MouseButton2",ActionHandler, false, Enum.UserInputType.MouseButton2)
ContextActionService:BindAction("F",ActionHandler, false, Enum.KeyCode.F)
ContextActionService:BindAction("Q",ActionHandler, false, Enum.KeyCode.Q)
return
else
local playerRecord = ClientPlayerRecord:GetPlayerRecord(self.Owner)
local PlayerViewmodel = playerRecord.Assets.Player.Viewmodel
local CombatStates = playerRecord.States.Combat
-- Unbind all actions
ContextActionService:UnbindAction("MouseButton1")
ContextActionService:UnbindAction("MouseButton2")
ContextActionService:UnbindAction("F")
ContextActionService:UnbindAction("Q")
PlayerViewmodel:Hide()
-- Stop charge
self:StopCharge()
-- Set states
CombatStates.IsChargeWaiting = false
self:Unblock()
-- Disconnect this event since we are no longer waiting for charge
playerRecord.FastSignals.AbleToCharge:DisconnectAll()
playerRecord.FastSignals.AbleToBlock:DisconnectAll()
if playerRecord.Connections.Rbxl.HideTrailOnHitAnimationStopped then
playerRecord.Connections.Rbxl.HideTrailOnHitAnimationStopped:Disconnect()
end
-- Kill all transition coroutines
-- Stop all anims
for i,Animation in pairs(PlayerViewmodel.Animator:GetChildren()) do
Animation:Destroy()
end
for i,AnimationTrack in pairs(PlayerViewmodel.AnimationTracks) do
AnimationTrack:Stop()
PlayerViewmodel.AnimationTracks[i] = nil
end
end
end)
return self
end
function Melee:Setup()
-- Load mods
ClientPlayerRecord = ClientMods:GetMod("clientmods","ClientPlayerRecord")
-- Load all of our networking Enums
Enums.MeleeData = {
Equip = 0,
Idle = 1,
Block = 2,
Shove = 3,
Charge = 4,
Hit = 5,
Inspect = 6
}
-- Load all the Enums for our animations!
Enums.Anims.FistsIdle = 7
Enums.Anims.FistsBlock = 8
Enums.Anims.FistsInspect = 9
Enums.Anims.FistsShove = 10
Enums.Anims.FistsCharge = 11
Enums.Anims.FistsLightHit = 12
Enums.Anims.FistsHeavyHit = 13
Enums.Anims.FistsEquip = 14
end
function Melee:HandleEvent()
end
function Melee:ProcessCommand()
end
return Melee
Please help you can see how the method :StocChargeExists()


