Help with improving custom hotbar system (And some other stuff)

So im working on a custom hotbar system to go with my inventory system, and theres a couple of things i want to achieve that i dont know how to

  • Hide the normal roblox hotbar & Inventory
  • Create keybinds to match the number of the weapon
  • Change all weapon Numbers when a tool is removed (example: tools in slot1 slot2 slot3, tool 2 is removed, i want slot3 to change to slot 2)
  • (Maybe) if it isnt to hard find a way to get rid of guns that were sent back into the inventory, that were already equipped
Videos of how it works / some bugs

Just a quick video on how it works, also gets the 3 point in action
(The hotbar numbers dont change on removal)

Current Code and Stuff

Creating the folders for players

game.Players.PlayerAdded:Connect(function(plr)
	local c = Instance.new("Folder", game.ReplicatedStorage.PlayerInvetorys)
	c.Name = plr.Name .. "Folder"

	local d = Instance.new("Folder", c)
	d.Name = "Inventory"
	
	local e = Instance.new("Folder", c)
	e.Name = "Hotbar"
end)

Main Script stuff is fired to


function GetRidOfTools(plr, char)
	if char:FindFirstChildWhichIsA("Tool") then
		char:FindFirstChildWhichIsA("Tool"):Destroy()
	end
	
	for i, v in ipairs(plr.Backpack:GetChildren()) do
		v:Destroy()
	end
end



game.ReplicatedStorage.TotallyCoolEvents.EquipGun.OnServerEvent:Connect(function(plr, d, c)
	local Char = plr.Character
	
	if c == "ToHotBar" then
		print("SendingToHotBar")
		if not d then return end
		if not Char then return end
		if not d:IsA("Tool") then return end
		local hbNum = #game.ReplicatedStorage.PlayerInvetorys:FindFirstChild(plr.Name .. "Folder"):WaitForChild("Hotbar"):GetChildren()
		if hbNum >= 8 then return "InvFull" end
		d.Parent = game.ReplicatedStorage.PlayerInvetorys:FindFirstChild(plr.Name .. "Folder"):WaitForChild("Hotbar")
	end
	
	if c == "ToInv" then
		if not d then return end
		if not Char then return end
		if not d:IsA("Tool") then return end
		d.Parent = game.ReplicatedStorage.PlayerInvetorys:FindFirstChild(plr.Name .. "Folder"):WaitForChild("Inventory")
	end
	
	if c == "EquipGun" then
		if not d then return end
		if not Char then return end
		if not d:IsA("Tool") then return end
		if Char:FindFirstChildWhichIsA("Tool") or plr.Backpack:FindFirstChildWhichIsA("Tool") then
			GetRidOfTools(plr, Char)
			local TrueGun = d:Clone()
		  	TrueGun.Parent = Char
		end
	end
end)

Inventory Code

local player = game.Players.LocalPlayer
local mainFolder = game.ReplicatedStorage.PlayerInvetorys:WaitForChild(player.Name .. "Folder")
local inv = mainFolder:WaitForChild("Inventory")
local hb = mainFolder:WaitForChild("Hotbar")
local CurrentInv = inv:GetChildren()
local C = game.ReplicatedStorage.ItemFrame
local hoverinv = script.Parent.Parent.HoverInfo
local mouse = player:GetMouse()
local InventoryFrames = {}
print(CurrentInv)


function equipitem(item, frame)
	if not item then warn("Wheres My Gun At?") return end
	hoverinv.Visible = false
	local D = game.ReplicatedStorage.TotallyCoolEvents.EquipGun:FireServer(item, "ToHotBar")
	if D ~= nil then
		print(D)
	end
end

local function Hover(item)
	hoverinv.Visible = true
	if item:FindFirstChild("strings") then
		hoverinv.GunName.Text = item.Name
		hoverinv.ExpNumber.Text = item.strings.CurrentExp.Value .. " / " .. item.strings.ReqExp.Value
		hoverinv.LvlNumber.Text = item.strings.GunLevel.Value
		hoverinv.GunDmg.Text = item.strings.Damage.Value
		hoverinv.GunRPM.Text = item.strings.FireRate.Value
		hoverinv.GunAmmo.Text = item.strings.Ammo.Value .. " / " .. item.strings.StoredAmmo.Value
		hoverinv.Tal1.Text = item.strings.T1.Value .. " | Unlocks @ Level " .. item.strings.ReqT1.Value
		hoverinv.Tal2.Text = item.strings.T2.Value .. " | Unlocks @ Level " .. item.strings.ReqT2.Value
		hoverinv.Tal3.Text = item.strings.T3.Value .. " | Unlocks @ Level " .. item.strings.ReqT3.Value
		hoverinv.Tal4.Text = item.strings.T4.Value .. " | Unlocks @ Level " .. item.strings.ReqT4.Value
	end
end

function Creation(item)
	local K = C:Clone()
	InventoryFrames[item] = K
	K.Text = item.Name
	K.Visible = true
	K.Parent = script.Parent.ISF
	
	K.MouseButton1Click:Connect(function()
		print(InventoryFrames)
		equipitem(item, K)
	end)
	
	K.MouseEnter:Connect(function()
		Hover(item)
	end)
	
	K.MouseLeave:Connect(function()
		hoverinv.Visible = false
	end)
end

function Deletion(item)
	local frame = InventoryFrames[item]
	frame:Destroy()
	InventoryFrames[item] = nil
end


for i, v in ipairs(CurrentInv) do
	Creation(v)
end

inv.ChildAdded:Connect(function(Child)
	Creation(Child)
end)

inv.ChildRemoved:Connect(function(Child)
	Deletion(Child)
end)

mouse.Move:Connect(function()
	if script.Parent.Visible == true then
		hoverinv.Position = UDim2.new(0,mouse.X,0,mouse.Y)
	end
end)

Hotbar Code (Basically used the inventory code but on the hotbar)

local player = game.Players.LocalPlayer
local mainFolder = game.ReplicatedStorage.PlayerInvetorys:WaitForChild(player.Name .. "Folder")
local inv = mainFolder:WaitForChild("Inventory")
local hb = mainFolder:WaitForChild("Hotbar")
local CurrentInv = inv:GetChildren()
local C = game.ReplicatedStorage["HotBarSlot#"]
local hoverinv = script.Parent.Parent.HoverInfo
local mouse = player:GetMouse()
local HotbarFrames = {}
print(CurrentInv)


function unequipitem(item, frame)
	if not item then warn("Wheres My Gun At?") return end
	hoverinv.Visible = false
	local D = game.ReplicatedStorage.TotallyCoolEvents.EquipGun:FireServer(item, "ToInv")
	if D ~= nil then
		print(D)
	end
end

function equipgun(item)
	if not item then warn("Wheres My Gun At?") return end
	hoverinv.Visible = false
	local D = game.ReplicatedStorage.TotallyCoolEvents.EquipGun:FireServer(item, "EquipGun")
	if D ~= nil then
		print(D)
	end
end

local function Hover(item)
	hoverinv.Visible = true
	if item:FindFirstChild("strings") then
		hoverinv.GunName.Text = item.Name
		hoverinv.ExpNumber.Text = item.strings.CurrentExp.Value .. " / " .. item.strings.ReqExp.Value
		hoverinv.LvlNumber.Text = item.strings.GunLevel.Value
		hoverinv.GunDmg.Text = item.strings.Damage.Value
		hoverinv.GunRPM.Text = item.strings.FireRate.Value
		hoverinv.GunAmmo.Text = item.strings.Ammo.Value .. " / " .. item.strings.StoredAmmo.Value
		hoverinv.Tal1.Text = item.strings.T1.Value .. " | Unlocks @ Level " .. item.strings.ReqT1.Value
		hoverinv.Tal2.Text = item.strings.T2.Value .. " | Unlocks @ Level " .. item.strings.ReqT2.Value
		hoverinv.Tal3.Text = item.strings.T3.Value .. " | Unlocks @ Level " .. item.strings.ReqT3.Value
		hoverinv.Tal4.Text = item.strings.T4.Value .. " | Unlocks @ Level " .. item.strings.ReqT4.Value
	end
end

function Creation(item)
	local K = C:Clone()
	local D = #hb:GetChildren()
	K.Name = "HotBarSlot#" .. D
	K.Number.Text = D
	HotbarFrames[item] = K
	K.Text = item.Name
	K.Visible = true
	K.Parent = script.Parent
	
	K.MouseButton1Click:Connect(function()
		if player.PlayerGui.Main.InvFrame.Visible == true then
			unequipitem(item, K)
		else
			equipgun(item)
		end
	end)
	
	K.MouseEnter:Connect(function()
		if player.PlayerGui.Main.InvFrame.Visible == true then
			Hover(item)
		end
	end)
	
	K.MouseLeave:Connect(function()
		hoverinv.Visible = false
	end)
end

function Deletion(item)
	local frame = HotbarFrames[item]
	frame:Destroy()
	HotbarFrames[item] = nil
end


for i, v in ipairs(hb:GetChildren()) do
	Creation(v)
end

hb.ChildAdded:Connect(function(Child)
	Creation(Child)
end)

hb.ChildRemoved:Connect(function(Child)
	Deletion(Child)
end)

The Structure of the gui
image

(Extra notes)
The main frames are cloned from replicated storage
image

Extra Stuff that i would love answered

Any idea how to make the gun not fire when the mouse is in a gui?
Heres the gun firing code

RunService.Stepped:Connect(function() 
	if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
		if not Tool.Parent:IsA("Backpack") or Tool.Parent:IsA("Folder") then
			if script.Parent.Strings.Ammo.Value >= 1 then
				local mPos = ms.Hit.Position

				FEvent:FireServer(mPos)		
			end	
		end
	end
end)

Also since im using fastcast, is there a way to get the bullets to not freeze in the air and break when a gun is destroyed
(As shown in the video)

  1. Roblox has a documentation on first bullet. In this case you need to turn the Enum.CoreGuiType.Backpack off.
local StarterGui = game:GetService("StarterGui")
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
  1. Second is binding events to key inputs using UserInput and assigning IDs to weapons.
  2. You can use table.sort(if your backpack is based on arrays) each time an item is removed to sort them by assigned IDs.

Ok, just wondering, does this only work ingame? and not in studio as its just not working for me

Was thinking about something similar to this, not sure how to do it

Not even sure what this means, probably due to my lack of knowledge

If you aren’t familiar what tables or arrays are you might as well read the documentation. In my opinion it will help with ordering things up. Each element of the table is indexed starting from 1. You can create a table of size 4 (meaning only 4 elements will be able to be fit in there) for it to act as an inventory. You also should use the table library to manipulate tables as you wish. I hope you will find these docs helpful.

Hi!

This might work for you. :slight_smile:

HotBar.Changed:Connect(function() -- When a new child is added/removed from our HotBar
	local HotbarIcons = {} -- We create an empty table
	for _, Icon in pairs(HotBar:GetChildren()) do -- We loop through all children of HotBar
		if Icon:IsA("ImageButton") or Icon:IsA("TextButton") then -- If HotBar is a ImageButton/TextButton, use what fits your script.
			table.insert(HotbarIcons,Icon) -- We insert our icon into our "empty" table
		end
	end
	table.sort(HotbarIcons, function(a,b) -- a & b is just a indication that we compare one value to another, and we do that through all our table. If a < b then put it back in line in our table.
		local A_string = a.Name:gsub('%D+', ''); -- we do so A.Name only contains numbers, since it sounds like you sort your slots by name.
		local B_string = b.Name:gsub('%D+', ''); -- we do so B.Name only contains numbers, since it sounds like you sort your slots by name.
		return tonumber(A_string) > tonumber(B_string) --tonumber turns something into a number-value. For example a string "1" into number 1
	end)
	for Index, Icon in ipairs(HotbarIcons) do -- We loop through our sorted table
		Icon.Name = "Slot"..Index -- We rename our icons to Slot, and the index they have in our sorted table.
	end
end)
1 Like

this looks like it might work, although im going to need a few hours to understand how it works

(Edit)
Mainly this part right here


This is a simplified demonstration.

1 Like

alright, i get that now, although what does this do

(edit)
Mainly Dont understand what _string is and what gsub is and how it works nor the text in gsub

A_string and B_string is just variables like everything else.

What we do is, we make a new variable. We say the new variable should be a.Name (which is the name of the current icon we’re checking in our table. We inserted the icon previously in the script)
We take that name, and we remove all letters, so only numbers are left. This is done with β€œa.Name:gsub(’%D+’, β€˜β€™)”. if β€˜%D+’ (letter), then replace the letter with β€˜β€™ (blank)

local NewName = a.Name:gsub('%D+', '');

Alright i get it, im guessing they get the number from the tables number? or does it get it some other way?

The numbers left behind in our variable, is the number that the icon was named after.
So if your icon is named β€œSlot1” it leaves behind β€œ1”, and β€œSlot7” leaves behind β€œ7”.

After inserting all icons, we sort the table.
After sorting the table, we have this:

local SortedTable = {
[1] = 1
[2] = 7
}

And then we run a ipairs loop through or sorted table, and change the iconName to the Index they have in the table. So Icon1 will stay Icon1 but Icon7 will be changed to Icon2

ooh im dumb, i forgot i added numbers to the names, lol i get it now

Quick question, anything else similar to .Changed i can use?, as when i use .Changed, it doesnt detect children being added/removed from the gui

Also still having a error with this if anyone could help :heart: