Custom face Gui has a Strange Problem

Howdy, developers!

I’m working on a custom face Gui in which you put in a face Id and the face will be applied to the user. For some strange reason, the user’s face is printed with a blank face. Everything else in the script works just fine.

Gui:
image

Local Script:

local Frame = script.Parent.Parent

local faceId

script.Parent.MouseButton1Click:Connect(function()

local plyr = game.Players.LocalPlayer

faceId = Frame.TextBox.Text

print(plyr)

print(faceId)

game.ReplicatedStorage.changeFaceId:FireServer(faceId)

end)

Script in ServerScriptServcie:


remoteEvent.OnServerEvent:Connect(function(player,faceId)
	print(faceId)
	local faceString = tostring(faceId)
	player.Character.Head.face.Texture = "http://www.roblox.com/asset/?id="..faceString
	print("success")
end)

Thanks.

2 Likes

Well are you trying to use a regular image ID or an actual official face provided by Roblox and taking the link from the website? The ID on the website and asset ID for the actual image of the face are different.

It requires some trial and error to get the right one. I know at some point it used to be the asset ID - 2 or something similar, but I heard it changed. With this, I’d recommend to use a plugin like Load Catalog Items by artfvl and try to find a pattern, then running a pcall() in a loop until a proper image ID is found.

Good luck!

1 Like

I’ll test that out soon, thanks!

I’m trying to implement an official face, forgot to mention.

This should work.

-- Client
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local changeFaceId = ReplicatedStorage.changeFaceId

local Player = Players.Player

local button = script.Parent
local frame = button.Parent

local inputBox = frame.TextBox

button.MouseButton1Click:Connect(function()
    local SetFaceId = tonumber(InputBox.Text) -- Verify if input is a number
    if SetFaceId then
        changeFaceId:FireServer(faceId)
    end
end)

-- Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local changeFaceId = ReplicatedStorage.changeFaceId

local link = "http://www.roblox.com/asset/?id="

changeFaceId.OnServerEvent:Connect(function(Player, Id)
    if type(Id) == "number" then
        -- Optionally here you can verify if the sent Id is really a Roblox "face" or decal.
        local Character = Player.Character
        local Head = Character and Character:FindFirstChild("Head")
        if Head then
            local faceDecal = Head:FindFirstChild("face") or Head:FindFirstChildOfClass("Decal")
            if faceDecal then
                faceDecal.Image = link .. tostring(Id)
            end
        end
    end
end)

Oh, that requires a little bit more editing to what I wrote. Essentially, you’ll need to load the asset via InsertService() and grab the faces content from the inserted model. I would recommend using my code as a base-line for that as it covers other flaws that your script contained.

I looked at your script, changed a few things, and boom, it worked.

Thanks a lot!

My mistake! I referenced decals and players the wrong way, still not used to Visual Code.
This version supports loading catalogue items rather than having to input the decal Id.

-- Server
local InsertService = game:GetService("InsertService")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local changeFaceId = ReplicatedStorage.changeFaceId

local function getDescendantFromAsset(assetId, assetType, data)
	-- Additionally, you can use a cache here to store previous loaded info
	local success, package = pcall(function()
		return InsertService:LoadAsset(assetId)
	end)
	if success then
		local asset = package:FindFirstChildOfClass(assetType)
		if asset then
			local re = asset[data]
			package:Destroy()
			return re
		else
			package:Destroy()
		end
	end
end

changeFaceId.OnServerEvent:Connect(function(player, assetId)
	if assetId and type(assetId) == "number" then
		local faceData = getDescendantFromAsset(assetId, "Decal", "Texture")
		if faceData then
			local head = player.Character and player.Character:FindFirstChild("Head")
			if head then
				local playerFace = head:FindFirstChild("face") or head:FindFirstChildOfClass("Decal")
				if playerFace then
					playerFace.Texture = faceData
				end
			end
		end
	end
end)
-- Client
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local changeFaceId = ReplicatedStorage.changeFaceId

local Player = Players.LocalPlayer

local button = script.Parent
local frame = button.Parent

local inputBox = frame.TextBox

button.MouseButton1Click:Connect(function()
	local faceId = tonumber(inputBox.Text) -- Verify if input is a number
	if faceId then
		changeFaceId:FireServer(faceId)
	end
end)
1 Like

It’s alright, I fixed your mistakes anyway. I’ll change this one to the solution though.