How to to stop images from blinking when updating their image id?

Hello, I made this in a specific way where it is too late for me to change it into a sprite sheet.

Notice how the head blinks whenever the image is changing. In this case I am using a decal on a part, updating the Texture property.

I made it using Moon Animator 2 and using the Moonlite module to play it in game.

Is there a way I can somehow preload them or any other way that stops it from blinking?

Perhaps there is a way you can integrate Video Player into Moonlite?

Thanks.

2 Likes

you can try using ContentProvider:PreloadAsync() to preload all of the decals.

the function takes in a list of instances to preload, and then yields until all of them have been loaded

1 Like

I already did that too.
Here’s my script

local function loadImages()
	local IDs = {
		"http://www.roblox.com/asset/?id=111144469804988",
		"http://www.roblox.com/asset/?id=73867945464814",
		"http://www.roblox.com/asset/?id=123638460370012",
		"http://www.roblox.com/asset/?id=94841909676652",
		"http://www.roblox.com/asset/?id=94747138789104",
		"http://www.roblox.com/asset/?id=135135026450497",
		"http://www.roblox.com/asset/?id=96549073161631",
		"http://www.roblox.com/asset/?id=135344714480892",
		"http://www.roblox.com/asset/?id=86494747510639",
		"http://www.roblox.com/asset/?id=94987789415917",
		"http://www.roblox.com/asset/?id=99532975119608",
		"http://www.roblox.com/asset/?id=84066209085445",
	}
	local function checkFailed(contentId, status)
		if status == Enum.AssetFetchStatus.Failure then
			print("Failed to load", contentId)
		else
			print("Success loaded", contentId)
		end
	end
	
	ContentProvider:PreloadAsync(IDs, checkFailed)
end

Maybe I did it wrong? Can you show me what you meant by that?

You could potentially create a new decal for each image, creating a buffer of a frame or two, loading them with a transparency of 1 until switching to that decal, and then discarding them once you’re done with them.

Can you try making a script for me?

maybe it doesn’t make a difference, but the official documentation preloads actual decals rather than ids.
can you see if making the IDs table a list of decals rather than ids changes anything?

also, make sure you are preloading on the client

I can do that, but I would have to start the entire animation all over again.

1 Like

yea, then you should try doing what @Marked4Destruction suggested.

you would take your list of ids, create a decal for each of them, set the transparency of each one to 1, and then when displaying that frame set the to transparency 0.

a mock up would look like this (thanks @Marked4Destruction for spotting an error)

-- Creating the decals --
local IDs = {
	"http://www.roblox.com/asset/?id=111144469804988",
	"http://www.roblox.com/asset/?id=73867945464814",
	"http://www.roblox.com/asset/?id=123638460370012",
	"http://www.roblox.com/asset/?id=94841909676652",
	"http://www.roblox.com/asset/?id=94747138789104",
	"http://www.roblox.com/asset/?id=135135026450497",
	"http://www.roblox.com/asset/?id=96549073161631",
	"http://www.roblox.com/asset/?id=135344714480892",
	"http://www.roblox.com/asset/?id=86494747510639",
	"http://www.roblox.com/asset/?id=94987789415917",
	"http://www.roblox.com/asset/?id=99532975119608",
	"http://www.roblox.com/asset/?id=84066209085445",
}

local partDecals = {}

for _, id in IDs do
    local decal = Instance.new("Decal")
    decal.Texture = id
    decal.Transparency = 1
    decal.Parent = part -- Set this to the part you are using
    table.insert(partDecals, decal)
end
-- Displaying them --
local previousDecal = nil
for _, decal in partDecals do
    decal.Transparency = 0
    if previousDecal ~= nil then
        -- We hide the previous frame after displaying the current frame, to try and reduce any possible stuttering
        previousDecal.Transparency = 1
    end
    task.wait(0.1) -- The delay between frames
    decal.Transparency = 1
    previousDecal = decal
end

let me know if that works!

2 Likes

Setting the transparency won’t do anything. Make the image visible and set the size to Udim.fromScale(0, 0).

1 Like

I was in the middle of mocking up a script, but you beat me to it :wink:
Don’t forget to set the decal’s Face when you create it.
Example:
decal.Face = Enum.NormalId.Top

1 Like

He is using decals not ImageLabels

Ah, right. In that case, since the decal is on a part, you could make the size of the part the smallest size possible while keeping the decal visible.

I already have it so that only one decal object is used, and it will have the images being updated by changing the Texture property so that’s not really an option in my case. Is there any other way?

I feel like using Zindex instead of transparency would be better as roblox might not load images with 1 as transparency.

Could you try my method? I have never tried it, but I do believe it has a good chance of it working. I remember seeing a post about the same issue but for ImageLabels. Their solution was to keep it visible and to set to size to 0, 0 to hide it. The same idea could be used for this problem.

You can’t change the size of a Decal. They fill the entire face of the part.

Yes, my suggestion is to update the size of the part, not the decal itself.

I also believe it works. My problem isn’t that your guys’s solutions aren’t working. It’s the fact that in my case, it would not be a good way of doing it

I tested your code and it works perfectly, as long as the image ID’s are preloaded

unfortunately, if it’s stuttering and PreloadAsync isn’t working, there isn’t much of an option other than using multiple decal instances to stop it.

2 Likes