What do you want to achieve? Keep it simple and clear!
I want to make a Custom Tool System similar to Decaying Winter, where you have a limited amount of inventory slot, and if you equip an empty slot you will have a fallback tool, for example: Fists.
What is the issue? Include screenshots / videos if possible!
The issue I am coming across is if I equip an empty slot (Fists) while already equipping another empty slot (Fists again) the bindable events for equipping and unequipping will fire correctly (first unequipping then equipping) the “equipped” value will stay as false. Mind the fact then when you equip an empty slot (Fists) the first time it equips them just fine.
In the image above you can see that the first equipped is fired correctly and the value is true.
But the second time equipping after unequipping the item, you can see that the value is false.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have tried looking for solutions on the web and also adding a delay before sending the equipped event, which while working had to be a significantly long time which made equipping not very responsive.
--|| SERVICES ||--
local players = game:GetService("Players")
local repStorage = game:GetService("ReplicatedStorage")
local inputService = game:GetService("UserInputService")
--|| PLAYER VARIABLES ||--
local player = players.LocalPlayer
--|| VARIABLES ||--
local currentItem = nil
local currentItemId = 0
local inventoryTable = {
[1] = {nil,"Melee"};
[2] = {nil,"Gun"};
[3] = {nil,"Slot"};
[4] = {nil,"Slot"};
}
local physicalInventory = player:WaitForChild("Inventory")
local physicalFallback = player:WaitForChild("FallbackItem")
local fallbackItem = physicalFallback:WaitForChild("Fists")
--|| UI VARIABLES ||--
local inventoryUI = script.Parent:WaitForChild("InventoryUI")
local itemFrame = inventoryUI:WaitForChild("ItemFrame")
local templateFolder = repStorage:WaitForChild("UITemplates")
local slotTemplate = templateFolder:WaitForChild("InventorySlot")
--|| EVENTS VARIABLES ||--
local eventsFolder = repStorage:WaitForChild("Events")
local inventoryHandler = eventsFolder:WaitForChild("InventoryHandler")
local equipItemEvent = inventoryHandler:WaitForChild("Equip")
local unequipItemEvent = inventoryHandler:WaitForChild("Unequip")
--|| FUNCTIONS ||--
function equipItem(id)
if inventoryTable[id][1] then
--Equip from physical inventory
else
--Equip fallback item
currentItem = fallbackItem
currentItemId = id
currentItem.Parent = player.Character
equipItemEvent:FireServer(currentItem)
currentItem.EquipEvent:Fire()
itemFrame["SLOT"..id].Item.Text.Text = "Fists"
itemFrame["SLOT"..id].Item.BackgroundColor3 = Color3.fromRGB(50,50,50)
itemFrame["SLOT"..id].Slot.BackgroundColor3 = Color3.fromRGB(50,50,50)
if currentItem:FindFirstChild("JointGrip") then
local visualGrip = currentItem:Clone()
visualGrip.Parent = workspace.CurrentCamera.Arms
visualGrip.Name = "Item"
for i,v in pairs(visualGrip:GetChildren()) do
if not v:IsA("Model") and not v:IsA("BasePart") then
v:Destroy()
end
end
local newJoint = Instance.new("Motor6D",visualGrip.JointGrip)
newJoint.Name = "GripJoint"
newJoint.Part0 = workspace.CurrentCamera.Arms.RightUpperArm
newJoint.Part1 = visualGrip.JointGrip
newJoint.C0 = CFrame.new(0,0,-1.25)
end
end
end
function unequipItem()
currentItem.UnequipEvent:Fire()
unequipItemEvent:FireServer(currentItem)
if currentItem ~= fallbackItem then
currentItem.Parent = physicalInventory
else
itemFrame["SLOT"..currentItemId].Item.Text.Text = "Empty"
currentItem.Parent = physicalFallback
end
itemFrame["SLOT"..currentItemId].Item.BackgroundColor3 = Color3.fromRGB(255,255,255)
itemFrame["SLOT"..currentItemId].Slot.BackgroundColor3 = Color3.fromRGB(255,255,255)
if workspace.CurrentCamera.Arms:FindFirstChild("Item") then
workspace.CurrentCamera.Arms.Item:Destroy()
end
currentItem = nil
end
function onInputBegan(input,chatted)
if chatted then return end
local number = tonumber(inputService:GetStringForKeyCode(input.KeyCode))
if number and number < #inventoryTable then
if not currentItem then
equipItem(number)
elseif (currentItem ~= inventoryTable[number][1]) then
if currentItem then
unequipItem()
end
equipItem(number)
end
end
end
function initializeUI()
for i,item in pairs(inventoryTable) do
local newSlot = slotTemplate:Clone()
newSlot.Name = "SLOT"..i
newSlot.Parent = itemFrame
newSlot.Slot.Text.Text = item[2].." - "..i
end
end
--|| CONNECTIONS ||--
inputService.InputBegan:Connect(onInputBegan)
--|| INITIALIZING ||--
initializeUI()
equipItem(1)
the equipped value seems to be set correctly when looking at it before equipping and before unequipping (the print is at the start of the equip and unequip functions), but it just seems like it doesn’t want to set the equipped value?
“Tool used! equipped = true” just says in which state the equipped value is in, when I use the tool (when an input is detected) it doesn’t set the equipped value.
Okay so, I used an auto clicker to force an update every frame and I noticed that after equipping there is like 1 - 2 frames where the equipped value is set to true but after that it goes back to false.
Edit: Also, if I set a task.wait() in a for i loop for the amount of frames that the equipped value is set to true, it will equip no problem.
local inputService = game:GetService("UserInputService")
local animations = script.Parent:WaitForChild("Animations")
local equipAnimation = nil
local idleAnimation = nil
local lightCombo1Animation = nil
local lightCombo2Animation = nil
local lightCombo3Animation = nil
local heavyAttackAnimation = nil
local blockAnimation = nil
local blockHitAnimation = nil
local shoveAnimation = nil
local equipped = false
local equipTick = tick()
local comboSpeed = 0.5
local heavySpeed = 2
local attacking = false
local canPerform = true
script.Parent.UnequipEvent.Event:Connect(function()
equipped = false
print("Unequipped")
if equipAnimation then
equipAnimation:Stop()
end
if idleAnimation then
idleAnimation:Stop()
end
if lightCombo1Animation then
lightCombo1Animation:Stop()
end
if lightCombo2Animation then
lightCombo2Animation:Stop()
end
if lightCombo3Animation then
lightCombo3Animation:Stop()
end
if heavyAttackAnimation then
heavyAttackAnimation:Stop()
end
if blockAnimation then
blockAnimation:Stop()
end
if blockHitAnimation then
blockHitAnimation:Stop()
end
if shoveAnimation then
shoveAnimation:Stop()
end
end)
script.Parent.EquipEvent.Event:Connect(function()
equipped = true
print("Equipped")
equipTick = tick()
if not equipAnimation then
equipAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("Equip"))
end
if not idleAnimation then
idleAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("Idle"))
end
if not lightCombo1Animation then
lightCombo1Animation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("LightCombo1"))
end
if not lightCombo2Animation then
lightCombo2Animation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("LightCombo2"))
end
if not lightCombo3Animation then
lightCombo3Animation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("LightCombo3"))
end
if not heavyAttackAnimation then
heavyAttackAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("HeavyAttack"))
end
if not blockAnimation then
blockAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("Block"))
end
if not blockHitAnimation then
blockHitAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("BlockHit"))
end
if not shoveAnimation then
shoveAnimation = workspace.CurrentCamera.Arms.Animator:LoadAnimation(animations:WaitForChild("Shove"))
end
idleAnimation:Play()
equipAnimation:Play()
equipAnimation:AdjustWeight(1,0)
end)
inputService.InputBegan:Connect(function(input,chatted)
print("Tool used! Equipped = "..tostring(equipped))
if not equipped or chatted or not canPerform or tick() - equipTick < 1 then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
attacking = true
canPerform = false
lightCombo1Animation:Play()
task.wait(comboSpeed)
if attacking and equipped then
lightCombo2Animation:Play()
task.wait(comboSpeed)
if attacking and equipped then
lightCombo3Animation:Play()
task.wait(comboSpeed)
end
end
attacking = false
canPerform = true
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
attacking = true
canPerform = false
heavyAttackAnimation:Play()
task.wait(heavySpeed)
attacking = false
canPerform = true
elseif input.KeyCode == Enum.KeyCode.Q then
canPerform = false
shoveAnimation:Play()
shoveAnimation:AdjustWeight(1,0)
task.wait(1)
canPerform = true
elseif input.KeyCode == Enum.KeyCode.R then
canPerform = false
blockAnimation:Play()
spawn(function()
local RNG = math.random(1,2)
if RNG == 1 then
task.wait(0.3)
blockHitAnimation:Play()
blockHitAnimation:AdjustWeight(1,0)
end
end)
task.wait(1)
canPerform = true
end
end)
inputService.InputEnded:Connect(function(input,chatted)
if chatted then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
attacking = false
end
end)