-
Issue
PWNed BY 14_00 [PROTOTYPE _ J) - Roblox Studio 2025-02-16 13-53-49.mp4 - Google Drive
The face’s decal becomes blurry on change. I would like for it to already be high-quality when changing it for my game -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried preloading the face’s texture each time I change the texture. And preloading it prematurely, before the face changes.
I tried layering decals on the face with a transparency of 0.999 and then making them visible. They also get briefly blurry on transparency changes as well.
I also messed around with Workspace.ModelStreamingBehavior. I think that’s completely unrelated though lol
If it helps, here’s my current code (preloadAsync runs on an UnreliableRemoteEvent—I can assure it runs before the face change by the console output):
local character = script.Parent.Parent.Parent
local dir = script.Parent
local preloadAsync = game.ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("PreloadAsync")
local face = character:WaitForChild("Head"):FindFirstChildOfClass("Decal")
local lowHpFace = dir.LowHp
local damagedFace = dir.Damaged
local normalFaceTexture = face.Texture
local LOW_HP_RATIO = 4 -- 100 maxhealth would be 25 health
local humanoid = character:WaitForChild("Humanoid")
local previousHp = humanoid.Health
local damagedFaceThread = nil
local DAMAGE_EXPRESSION_DURATION = 1
-- preload faces on script run
preloadAsync:FireAllClients({lowHpFace.Texture, damagedFace.Texture})
-- meant to run on task.spawn when not forever
local function onDamaged(forever : boolean)
preloadAsync:FireAllClients({damagedFace.Texture})
face.Texture = damagedFace.Texture
if not forever then
preloadAsync:FireAllClients({normalFaceTexture})
task.wait(DAMAGE_EXPRESSION_DURATION)
face.Texture = normalFaceTexture
damagedFaceThread = nil
end
end
local function cancelDamageThread()
if damagedFaceThread then
task.cancel(damagedFaceThread)
damagedFaceThread = nil
end
end
humanoid:GetPropertyChangedSignal("Health"):Connect(function()
local isLowHp = humanoid.Health <= humanoid.MaxHealth / LOW_HP_RATIO
if isLowHp then
if not damagedFaceThread then
damagedFaceThread = task.spawn(onDamaged)
repeat
task.wait()
until not damagedFaceThread
if not damagedFaceThread then
face.Texture = lowHpFace.Texture
end
previousHp = humanoid.Health
return
end
else
-- determine if hp was gained
if humanoid.Health > previousHp and not isLowHp then
cancelDamageThread()
face.Texture = normalFaceTexture
else
-- on hit: avoid overlapping
if not damagedFaceThread then
damagedFaceThread = task.spawn(onDamaged)
end
end
end
previousHp = humanoid.Health
end)
humanoid.Died:Connect(function()
cancelDamageThread()
onDamaged(true)
end)
Any help’s appreciated. I at least know it’s possible due to Forsaken doing it smoothly—I just don’t know how.