Local hats change for npc

hi, I’m making classes for my game, and I need the class hats to be shown on the NPC, that is, how this hat will look on the player, and I can’t write it in a local script, I tried to implement it using RemoteEvent, but nothing really helped.

Here is the local script itself:

local RS = game:GetService("ReplicatedStorage")
local Module = require(RS:WaitForChild("ClassesModule"))
local player = game.Players.LocalPlayer
local Remotes = RS:WaitForChild("Remotes")

local buttons = script.Parent.Classes.ScrollingFrame:GetDescendants()
local playerData = Remotes.GetPlayerClasses:InvokeServer()
local equippedClass = player:FindFirstChild("ClassEquipped") and player.ClassEquipped.Value or nil
wait(2)

local npc = workspace:FindFirstChild("NpcClasses")
local function updateButtonText(className)
	local BuyButton = script.Parent.Stats:FindFirstChild("Button")
	if BuyButton then
		if playerData[className] then
			if equippedClass == className then
				BuyButton.Text = "UNEQUIP"
			else
				BuyButton.Text = "EQUIP"
			end
		else
			BuyButton.Text = "BUY"
		end
	end
end

local function changeNPCHat(className)
	if not npc then return end

	for _, accessory in ipairs(npc:GetChildren()) do
		if accessory:IsA("Accessory") and RS.HatsClasses:FindFirstChild(accessory.Name) then
			accessory:Destroy()
		end
	end

		local classAccessory = RS.HatsClasses:FindFirstChild(className)
		if classAccessory then
			local accessoryClone = classAccessory:Clone()
			accessoryClone.Parent = npc
	end
end

for _, button in ipairs(buttons) do
	if button:IsA("TextButton") then
		local titleLabel = script.Parent.Stats:FindFirstChild("ClassName")
		local descriptionLabel = script.Parent.Stats:FindFirstChild("Description")
		local PriceLabel = script.Parent.Stats:FindFirstChild("Price")
		local BuyButton = script.Parent.Stats:FindFirstChild("Button")

		button.MouseButton1Click:Connect(function()
			local className = button.Name
			for _, classData in ipairs(Module) do
				if classData.Name == className then
					changeNPCHat(className)
					titleLabel.Text = classData.Name
					descriptionLabel.Text = classData.Description
					PriceLabel.Text = classData.Price
					script.Parent.ClassSelected.Value = className
					updateButtonText(className)

					break
				end
			end
		end)
	end
end

script.Parent.ClassSelected:GetPropertyChangedSignal("Value"):Connect(function()
	local className = script.Parent.ClassSelected.Value
	updateButtonText(className)
end)

local className = script.Parent.ClassSelected.Value
updateButtonText(className)

script.Parent.Stats.Button.MouseButton1Click:Connect(function()
	local className = script.Parent.ClassSelected.Value
	local BuyButton = script.Parent.Stats.Button

	if BuyButton.Text == "BUY" then
		for _, classData in ipairs(Module) do
			if classData.Name == className then
				if player.leaderstats.Cash.Value >= classData.Price then
					player.leaderstats.Cash.Value -= classData.Price
					Remotes.ClassBuy:FireServer(className)
					playerData[className] = true
					BuyButton.Text = "EQUIP"
					updateButtonText(className)
				end
				break
			end
		end
	elseif BuyButton.Text == "EQUIP" then
		Remotes.EquipClass:FireServer(className, true)
		equippedClass = className
	elseif BuyButton.Text == "UNEQUIP" then
		Remotes.EquipClass:FireServer(className, false)
		equippedClass = nil
	end

	updateButtonText(className)
end)

once again, I tried to fix it via RemoteEvent, but the event wasn’t sent to the client, so now I’m trying to do it exclusively on the client side.

Edit the changeNPCHat function:

local function changeNPCHat(className)
    if not npc then return end

    for _, accessory in ipairs(npc:GetChildren()) do
        if accessory:IsA("Accessory") and RS.HatsClasses:FindFirstChild(accessory.Name) then
            accessory:Destroy()
        end
    end

    local classAccessory = RS.HatsClasses:FindFirstChild(className)
    if classAccessory then
        local accessoryClone = classAccessory:Clone()
        accessoryClone.Parent = npc

        local attachmentPart = npc:FindFirstChild("Head") or npc.PrimaryPart
        if attachmentPart and accessoryClone:FindFirstChild("Handle") then
            local attachment = accessoryClone.Handle:FindFirstChildOfClass("Attachment")
            if attachment then
                local npcAttachment = attachmentPart:FindFirstChild(attachment.Name)
                if npcAttachment then
                    accessoryClone.Handle.CFrame = npcAttachment.CFrame
                end
            end
        end
    end
1 Like

The accessory appeared inside the NPC, but it doesn’t show on it, maybe I can fix it now.

If you can fix it and my post helped, please mark it as the solution :white_check_mark:
ty

1 Like

I’m trying, but nothing works, at least I just need to change the position of the accessory somehow, but I just can’t figure out how

In the accessory properties window, use this to help you:

image

You can use this in a script, but if the accessory is not moving on the NPC, then just config this until it is adjusted properly.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.