Top.Mail.Ru
Ответы

Помогите пожалуйста со скриптам

Предоставлю вам свои скрипты связанные с проблемой применения одежды на персонажа, у меня следующая задумка: Игрок подходит к примеру к нпс и зажимает E, открывается интерфейса магазина одежда, камера приближает немного скин игрока и смотрит как бы спереди на него, чтоб при выборе одежды к примеру тип одежды: Shirt, при его выборе чтоб футболка на игроке удалялась и одевалась выбранная из Scrolling Frame, правее от него кнопки категории (AccessoriesButton, PantsButton, ShirtsButton) в этом же порядке вертикально, при сохранении выбранная одежда сохраняется на игроке при всех последующих заходах в игру, при закрытии интерфейса, если была выбрана какая-то одежда, то она становится прежней, также я использую DataStore2, так как собираюсь делать сложную игру, пожалуйста помогите буду очень вам благодарен

Структура Gui:

StarterGui

└── ClothingShopGUI

├── ShopMenu

│ ├── CategoryPanel

│ │ ├── ShirtButton

│ │ ├── PantsButton

│ │ ├── AccessoriesButton

│ └── ClothesPanel

└── Templates

└── TemplateButton (ImageButton)


Клиентский скрипт:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
local player = game.Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local shopGui = player.PlayerGui.ClothingShopGui
local shopMenu = shopGui.ShopMenu
local clothesPanel = shopMenu.ClothesPanel
local categoryPanel = shopMenu.CategoryPanel
local templateButton = shopGui.Templates.TemplateButton
local createdButtons = {}

-- Список всех доступных предметов
local outfits = {
	["Shirt"] = {
		["Los California"] = {
			AssetId = 128196044584927,
		},
	},
	["Pants"] = {
		["Black Jeans"] = {
			AssetId = 382537568,
		},
	},
	["Accessories"] = {
		["T-Shirt-Black"] = {
			AssetId = 6964007640,
		},
		["Glasses"] = {
			AssetId = 6968110631,
		},
	},
}

-- Текущая категория
local currentCategory = "Shirt"

-- RemoteEvents
local wearItemEvent = ReplicatedStorage:FindFirstChild("WearItem")
if not wearItemEvent then
	warn("RemoteEvent 'WearItem' не найден в ReplicatedStorage!")
end

-- Функция очистки GUI
function clearGUI()
	for _, btn in ipairs(createdButtons) do
		btn:Destroy()
	end
	table.clear(createdButtons)
end

-- Функция создания кнопок для выбранной категории
function generateButtonsForCategory(category)
	clearGUI()

	local items = outfits[category]
	if not items then return end

	for name, data in pairs(items) do
		local btn = templateButton:Clone()
		btn.Name = name
		btn.Image = "rbxassetid://116862680140339" -- дефолтное изображение
		btn:SetAttribute("AssetId", data.AssetId)
		btn:SetAttribute("Kind", category:lower()) -- shirt / pants / accessory
		btn.Visible = true
		btn.Parent = clothesPanel
		table.insert(createdButtons, btn)

		btn.MouseButton1Click:Connect(function()
			if wearItemEvent and data and data.AssetId then
				local kind = string.lower("kind")
				print("Надеваем:", kind, data.AssetId)
				wearItemEvent:FireServer(data.AssetId, kind:sub(1,1):upper()..kind:sub(2))
			else
				warn("Ошибка: RemoteEvent не найден или отсутствует data.AssetId")
			end
		end)
	end
end

-- Обработчик клика на категории
function onCategoryButtonClick(category)
	currentCategory = category
	generateButtonsForCategory(category)
end

-- Подключаем события для кнопок категорий
categoryPanel.ShirtButton.MouseButton1Click:Connect(function()
	onCategoryButtonClick("Shirt")
end)

categoryPanel.PantsButton.MouseButton1Click:Connect(function()
	onCategoryButtonClick("Pants")
end)

categoryPanel.AccessoriesButton.MouseButton1Click:Connect(function()
	onCategoryButtonClick("Accessory")
end)

-- Инициализация при открытии магазина
generateButtonsForCategory(currentCategory)

Серверный скрипт:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
print("Серверный скрипт запущен!")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Http = game:GetService("HttpService")
local Players = game:GetService("Players")

-- === Создаём RemoteEvent'ы ===
local wearEv = Instance.new("RemoteEvent", ReplicatedStorage); wearEv.Name = "WearItem"
local quitEv = Instance.new("RemoteEvent", ReplicatedStorage); quitEv.Name = "QuitCustom"
local saveEv = Instance.new("RemoteEvent", ReplicatedStorage); saveEv.Name = "SaveCustom"

print("RemoteEvents созданы")

-- Подключаем DataStore2
local success, DataStore2 = pcall(require, game.ServerScriptService:FindFirstChild("DataStore2"))
if success then
	print("DataStore2 подключен")
else
	warn("Ошибка подключения DataStore2:", DataStore2)
end

local originals = {} -- оригинальные описания для отката

-- === WearItem: одеваем штаны/майки/аксессуары ===
wearEv.OnServerEvent:Connect(function(plr, assetId, kind)
	print("Тип assetId:", typeof(assetId))
	print("Значение assetId:", assetId)
	print("Получено событие:", plr.Name, kind, assetId)

	local char = plr.Character or plr.CharacterAdded:Wait()
	local hum = char:FindFirstChildOfClass("Humanoid")
	if not hum then return warn("Humanoid не найден у игрока", plr.Name) end

	originals[plr] = originals[plr] or hum:GetAppliedDescription()

	-- Удаляем старую одежду
	for _, child in pairs(char:GetChildren()) do
		if kind == "shirt" and child:IsA("Shirt") then
			child:Destroy()
		elseif kind == "pants" and child:IsA("Pants") then
			child:Destroy()
		elseif kind == "shirtgraphic" and child:IsA("ShirtGraphic") then
			child:Destroy()
		elseif kind == "accessory" and (child:IsA("Accessory") or child:IsA("Model")) then
			child:Destroy()
		end
	end

	local desc = hum:GetAppliedDescription()

	if kind == "shirt" then
		desc.Shirt = tonumber(assetId)
	elseif kind == "pants" then
		desc.Pants = tonumber(assetId)
	elseif kind == "shirtgraphic" then
		desc.Graphic = tonumber(assetId)  -- ✅ Правильное поле
	elseif kind == "accessory" then
		desc.HatAccessory = tostring(assetId)
	end

	hum:ApplyDescription(desc)

	-- Диагностика
	print("Shirt:", desc.Shirt)
	print("Pants:", desc.Pants)
	print("Graphic:", desc.Graphic or "нет графики")  -- ✅ Исправленный вывод
	print("HatAccessory:", desc.HatAccessory or "нет аксессуара")
end)

-- === QuitCustom: отмена кастомизации ===
quitEv.OnServerEvent:Connect(function(plr)
	local char = plr.Character
	if char and originals[plr] then
		local hum = char:FindFirstChildOfClass("Humanoid")
		if hum then
			hum:ApplyDescription(originals[plr])
		end
	end
end)

-- === SaveCustom: сохранение гардероба через DataStore2 ===
local saveDebounce = {}

local function scheduleSave(plr)
	if saveDebounce[plr] then return end
	saveDebounce[plr] = true

	delay(3, function()
		local char = plr.Character
		if not char then return end

		local hum = char:FindFirstChildOfClass("Humanoid")
		if not hum then return end

		local data = hum:GetAppliedDescription()

		local serializableData = {
			Shirt = data.Shirt,
			Pants = data.Pants,
			ShirtGraphic = data.Graphic,

			HatAccessory = data.HatAccessory,
			FaceAccessory = data.FaceAccessory,
			HairAccessory = data.HairAccessory,

			HeadColor = (data.HeadColor and data.HeadColor:ToHex()) or BrickColor.new("White"):ToHex(),
			TorsoColor = (data.TorsoColor and data.TorsoColor:ToHex()) or BrickColor.new("White"):ToHex(),
		}

		local blob = Http:JSONEncode(serializableData)

		local store = DataStore2("AvatarData", plr)
		local success, err = pcall(function()
			store:Set(blob)
		end)

		if not success then
			warn("Не удалось сохранить данные игрока " .. plr.Name, err)
		else
			print("Данные игрока " .. plr.Name .. " успешно сохранены")
		end

		saveDebounce[plr] = false
	end)
end

saveEv.OnServerEvent:Connect(function(plr)
	if originals[plr] then
		scheduleSave(plr)
	else
		warn("Нет данных для сохранения у игрока", plr.Name)
	end
end)

-- === Загрузка при входе ===
Players.PlayerAdded:Connect(function(plr)
	local store = DataStore2("AvatarData", plr)
	local savedBlob = store:Get(nil)

	if savedBlob then
		local success, savedData = pcall(Http.JSONDecode, Http, savedBlob)
		if success and savedData then
			plr.CharacterAppearanceLoaded:Wait()
			local char = plr.Character or plr.CharacterAdded:Wait()
			local hum = char:FindFirstChildOfClass("Humanoid") or char:WaitForChild("Humanoid", 10)
			if hum then
				local desc = Instance.new("HumanoidDescription")
				for propertyName, value in pairs(savedData) do
					if string.find(propertyName, "Color") then
						local color = BrickColor.new("White")
						pcall(function()
							color = BrickColor.new(Color3.fromHex(value))
						end)
						desc[propertyName] = color
					elseif desc[propertyName] ~= nil then
						desc[propertyName] = value
					end
				end
				hum:ApplyDescription(desc)
			end
		end
	end
end)


Видео по теме