ROBLOX — Примитивный инвентарь — Primitive inventory

Автор: | 5 февраля, 2025
Поделиться...

Я тут недавно подумал что цикл уроков превращает в какую-то микро игру в жанре RPG или выживача. В принципе я люблю и то и другое.

Продолжим. Что надо после того как ресурсы добыл? Сложить их в инвентарь! Вот его то и сделаем сейчас. Мы не будем изгаляться с супер-пупер инвентарём. Стаки ресурсов, ограничители по весу и/или объёму положенного, да и вообще с количеством ячеек. И уж тем более не будем хранить ничего в БД Роблакса и тем более за его пределами. У нас будет обычная фиговина, что будет считать количество ресурсов доступных игроку. Этого будет достаточно, чтобы в последствии сделать «примитивный» крафт предметов.

А по сути, инвентарь это обычная таблица в которой хранятся пары: что — сколько.

Погнали! В нашем скрипте инструмента есть строчки:

					if val > 0  then
						warn("Получено:", name, val)
					end

Вот в этом месте мы и будем добавлять в наш инвентарь что мы добыли. А с учётом того, что у нас скрипт инструмента серверный, то и заморачиваться с проверками (что и сколько добыли и не чит ли это ленивого игрока) мы не будем.

В персонаже хранить нельзя, в workspace — в принципе то же не стоит. Поэтому будем хранить в player — это место которое существует, пока игрок в игре. Но и просто в игроке тоже не стоит, «мусора» может стать ну очень много, поэтому нам нужна папка в игроке. И тут мы сталкиваемся с тем, что в режиме редактирования игры в Studio, мы не можем там разместить папку. Самый примитивный вариант это поместить её StarterPlayer/StarterPlayerScripts, но она будет утоплена в игроке. Второй вариант создать её скриптом на этапе подключения игрока. И я выбираю именно этот вариант.

Возьмём из документации образец подключения игрока и просто вставим там создание папки. Лишнее удалять не будем, оно может нам позже пригодиться. Назовём его — PlayerLoader и поместим в положенное место — ServerScriptService.

-- будет работать при подключении игрока и спавне/респавне персонажей

local Players = game:GetService("Players")

local function onCharacterAdded(character)
	print(character.Name .. " has spawned")
end

local function onCharacterRemoving(character)
	print(character.Name .. " is despawning")
end

local function onPlayerAdded(player)
	player.CharacterAdded:Connect(onCharacterAdded)
	player.CharacterRemoving:Connect(onCharacterRemoving)
	
	-- добавить папку инвентаря
	local invent = Instance.new("Folder")
	invent.Name = "Inventory"
	invent.Parent = player
end

Players.PlayerAdded:Connect(onPlayerAdded)

После запуска видим нужную папку.

Что же, теперь вернёмся к нашему скрипту с ресурсами и сохраним, кровно заработанное, в нашем инвентаре. Т.е. просто найдём нужный ресурс в этой папке и увеличим его значение на добытое число. Вот что получается:

					if val > 0  then
						warn("Получено:", name, val)
						
						local character = script.Parent.Parent						-- персонаж
						local player = Players:GetPlayerFromCharacter(character)	-- игрок
						local invent = player:FindFirstChild("Inventory")
						if invent then	-- инвентарь уже должен быть (это контрольный выстрел)
							local saveRes = invent:FindFirstChild(name) -- ищем ресурс
							if saveRes == nil then	-- если ещё его не считали
								saveRes = Instance.new("NumberValue")	-- создаём новую запись
								saveRes.Name = name
								saveRes.Value = 0
								saveRes.Parent = invent
							end
							saveRes.Value = saveRes.Value + val	-- обновляем значение
						end
					end

Запустили и получили что хотели. Теперь добавим это изменение и в кирку. Особо смышлёные могут почитать про module и как подключать функции оттуда, чтобы в каждом инструменте не заниматься копи-пастом. Но у нас всего два инструмента и.. мне всё равно на это сейчас.

Итак, первую часть выполнили — ресурсы считаются и хранятся. Вторая часть будет отобразить инвентарь. Не буду делать ничего красочного (не в этом задача), а просто создадим на экране табличку с текущими составляющими нашего инвентаря. В StarterGui накидаем подобное:

И в его LocalScript поместим следующий код:

local Players = game:GetService("Players")
local player = Players.LocalPlayer 

screen = script.Parent								-- наш экран
local sf = screen:WaitForChild("ScrollingFrame")	-- наше отображение
local sample = sf:WaitForChild("Sample"):Clone()	-- заготовка
local ui = sf:WaitForChild("UIListLayout"):Clone()	-- размещатель

local invent = player:WaitForChild("Inventory")		-- ссылка на инвентарь

while task.wait(.1) do	-- бесконечное обновление
	sf:ClearAllChildren()							-- зачистить от всех элементов
	local uic = ui:Clone()							-- копия копии UI
	uic.Parent = sf									-- пихаем в список
	
	for _, res in pairs(invent:GetChildren()) do	-- перебираем
		local element = sample:Clone()				-- копия копии элемента
		element.Names.Text = res.Name				-- укажем имя
		element.Amount.Text = res.Value				-- укажем значение
		element.Parent = sf							-- поместим в список
	end
end

Ну и запустим. Побегаем, подолбим и порубим!

Примитивный инвентарь готов.

Ну и собственно сам плейс прилагается, потому как мне очень не хочется писать как сделать GUI…


Поделиться...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *