DOOM Screen Melt effect

How can I recreate DOOM’s “Screen Melt” effect?
ezgif-1-24ad881f53

i have tried searching for this in the dev forum, but could not find anything

2 Likes

melt-ezgif.com-optimize

heres a solution that involves the ClipsDescendants property of the GuiObject class

basically for a given imagelabel we can subdivide it or basically “cut” it into a set of frames so the image looks full and unaltered, except we can move each individual slice

for a given slice width (i picked 4 pixels) we’ll just create a frame with that width and ClipsDescendants on.
then we can parent the cloned image to that frame and offset the cloned image by the total offset so it is placed at (0,0) which is the top left corner of the scrfeen, thus completing the illusion

if you notice in the doom melt screen, the falling of slices is random but continuous between slices. so we have to set a variable to track time (i picked 3000ms by default) . every iteration of a loop we can alter the baseline by a set but random amount. i picked math.random(-20,20), so every iteration the time can change by 20milliseconds

then we task.wait(ms/1000) and tween the individual slice to be off screen, creating the melting look

code
--// init
local gui = script.Parent; -- ScreenGui
local preimage = gui.screen; -- ImageLabel

local meltSectionWidth = 4;

local TWEEN_SERVICE = game:GetService("TweenService");



--// functions
function tween(instance:Instance,tweenTime:number,easingStyle:Enum.EasingStyle,easingDirection:Enum.EasingDirection,properties:{})
	local tween = TWEEN_SERVICE:Create(instance,TweenInfo.new(tweenTime,easingStyle,easingDirection),properties);
	tween:Play();
end

local function newClippingFrame(width : number, position : UDim2, image : ImageLabel, parent : Instance)
	-- frame
	local frame = Instance.new("Frame");
	
	frame.Size = UDim2.new(0,width,1,0);
	frame.Position = position;
	frame.BackgroundTransparency = 1.0;
	
	frame.ClipsDescendants = true;
	frame.Parent = parent;
	
	
	
	-- image
	local clone = image:Clone();
	
	clone.Visible = true;
	clone.Size = UDim2.fromOffset(image.AbsoluteSize.X,image.AbsoluteSize.Y);
	
	clone.Parent = frame;
	
	
	
	-- returns
	return frame,clone;
end



--// runtime
local ms = 3000;
for offset = 0,gui.AbsoluteSize.X,meltSectionWidth do
	local frame,image = newClippingFrame(meltSectionWidth,UDim2.fromOffset(offset,0),preimage,gui);
	image.Position = UDim2.fromOffset(-offset,0);
	
	task.spawn(function()
		task.wait(ms/1000);
		
		tween(image,1.5,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,{Position = UDim2.new(0,-offset,2,0)});
	end)
	
	ms += math.random(-20,20);
end
1 Like

thanks, this worked, only issue is that the imagelabel has to have the Visible property set off

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