How to make a killfeed system?

The idea is when a nextbot kills a player it appears on the screen like this:
image
It shows the image of the nextbot, the player who was killed and the nextbot who killed them

This is controlled by a RemoteEvent, when its fired with certain parameters then a script can recieve it and make the kill appear, here is my code:

local ts = game:GetService("TweenService")

local player = game.Players.LocalPlayer
local main = player.PlayerGui:WaitForChild("Main")
local mainFrame = main:WaitForChild("MainFrame")
local killFrame = mainFrame:WaitForChild("Killfeed")

local killExample = killFrame:WaitForChild("Kill")

function moveDown(frame, up)
	local tween = ts:Create(frame, TweenInfo.new(0.5), { 
		Position = frame.Position + UDim2.new(0, 0, up and -0.2 or 0.2, 0) 
	})
	
	tween:Play()
end

killFrame.ChildAdded:Connect(function()
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v)
	end
end)

killFrame.ChildRemoved:Connect(function()
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v, true)
	end
end)

game.ReplicatedStorage:FindFirstChild("KillFeed").OnClientEvent:Connect(function(target, killer, image)
	local newKill = killExample:Clone()
	newKill.Parent = killFrame
	newKill.Visible = true
	
	local information = newKill.Information
	information.Text = target .. " was killed by " .. killer
	
	local killerImage = newKill.KillerImage
	killerImage.Image = image
	
	task.wait(10)
	
	newKill:Destroy()
end)

I’ve never really done anything like this so something is bound to go wrong, and it has…

The kills are overlapping, not moving correctly and a whole lot more.

Does anyone have any experience in this sort of thing?

Gui is organized like this:
image

Whenever there’s a Child Added you move everything down… (couldn’t post more dots :pensive:) including the newly added kill feed message.

If I recall correctly, there should be a parameter for ChildAdded which is the newly added child, which you can use. While, you’re iterating through every single frame in killFrame you should check if the frame is the newly added child and if so, continue, like this:

killFrame.ChildAdded:Connect(function(child: Instance)
	for i, v in pairs(killFrame:GetChildren()) do
        if child == v then
           continue
        end
		moveDown(v)
	end
end)

And on a side note, you’re making everything go down whenever something gets removed from killFrame. It should go up.
Edit: Didn’t properly read the full code, ignore the text above (although you should be properly naming stuff to prevent confusion in the future)

To usually make multiple frames appear in a list i use a UIListLayout, though it doesn’t work with tweens, but if that’s not your solution you could also try moving every child of killFrame before the child is cloned, you can use RemoteEvents for this, since i’ve noticed that as soon as a new frame gets added it moves every single frame, including the new frame as far as i know, which could be the reason of your killfeed overlapping. (or you could combine ChildAdded with OnClientEvent into a single function.)

-- Perhaps instead of moving *after* the child has been added, you could move it *before* it does
-- so instead of this:

killFrame.ChildAdded:Connect(function()
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v)
	end
end)

game.ReplicatedStorage:FindFirstChild("KillFeed").OnClientEvent:Connect(function(target, killer, image)
	local newKill = killExample:Clone()
	newKill.Parent = killFrame
	newKill.Visible = true
	
	local information = newKill.Information
	information.Text = target .. " was killed by " .. killer
	
	local killerImage = newKill.KillerImage
	killerImage.Image = image
	
	task.wait(10)
	
	newKill:Destroy()
end)

-- You'd have this:
game.ReplicatedStorage:FindFirstChild("KillFeed").OnClientEvent:Connect(function(target, killer, image)
    -- Basically combined both functions into one, which triggers upon OnClientEvent.

    -- So the frames move *before* a child is added.
    for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v)
	end
    
    -- And then add the child
	local newKill = killExample:Clone()
	newKill.Parent = killFrame
	newKill.Visible = true
	
	local information = newKill.Information
	information.Text = target .. " was killed by " .. killer
	
	local killerImage = newKill.KillerImage
	killerImage.Image = image
	
	task.wait(10)
	
	newKill:Destroy()
end)


You can keep the ChildRemoved function as is as far as i know.

Hope this helps!

local ts = game:GetService("TweenService")

local player = game.Players.LocalPlayer
local main = player.PlayerGui:WaitForChild("Main")
local mainFrame = main:WaitForChild("MainFrame")
local killFrame = mainFrame:WaitForChild("Killfeed")

local killExample = killFrame:WaitForChild("Kill")

function moveDown(frame, up)
	local tween = ts:Create(frame, TweenInfo.new(0.5), { 
		Position = frame.Position + UDim2.new(0, 0, up and -0.1 or 0.1, 0) 
	})
	
	tween:Play()
end

killFrame.ChildRemoved:Connect(function()
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v, true)
	end
end)

game.ReplicatedStorage:FindFirstChild("KillFeed").OnClientEvent:Connect(function(target, killer, image)
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v)
	end

	local newKill = killExample:Clone()
	newKill.Parent = killFrame
	newKill.Visible = true
	
	newKill.Position = UDim2.new(0.688, 0,0.01, 0)

	local information = newKill.Information
	information.Text = target .. " was killed by " .. killer

	local killerImage = newKill.KillerImage
	killerImage.Image = image

	task.wait(10)

	newKill:Destroy()
end)

Alright I’ve made them move down when the event is fired then I create a new frame, this prevents the new frame from moving down aswell, problem now is when one is removed they go way off screen if theres too many

I’m not exactly sure what to call the new problems but I think the overlapping problem is multiple nextbots killing the player at the same time.

Here is the Gui:
thatsit.rbxm (8.3 KB)

And a new video showing the problems:

I’m not very good at explaining things, but if you want to reproduce the issues put the gui into startergui, add a remoteevent into replicatedstorage and call it KillFeed and then put a script into the workspace with these contents:

task.wait(2)
for i = 1, 10 do
	game.ReplicatedStorage:FindFirstChild("KillFeed"):FireAllClients("PlayerName", "Nextbot", "7120897383")
	task.wait(0.5)
end

I have tinkered around a bit, i’ve found out that if you have a tween move the newKill offscreen and then destory it after the tween is finished it’ll work.

Here’s a video to show what i mean:

Here’s the code:

local ts = game:GetService("TweenService")

local player = game.Players.LocalPlayer
local main = player.PlayerGui:WaitForChild("Main")
local mainFrame = main:WaitForChild("MainFrame")
local killFrame = mainFrame:WaitForChild("Killfeed")

local killExample = killFrame:WaitForChild("Kill")

function moveDown(frame, up)
	local tween = ts:Create(frame, TweenInfo.new(0.5), { 
		Position = frame.Position + UDim2.new(0, 0, up and -0.1 or 0.1, 0) 
	})

	tween:Play()
end

-- I've commented ChildRemoved out in case it's needed again if the thing happened to not work.
--killFrame.ChildRemoved:Connect(function()
--	for i, v in pairs(killFrame:GetChildren()) do
--		moveDown(v, true)
--		--task.wait(0.1)
--	end
--end)

game.ReplicatedStorage:FindFirstChild("KillFeed").OnClientEvent:Connect(function(target, killer, image)
	for i, v in pairs(killFrame:GetChildren()) do
		moveDown(v)
	end

	local newKill = killExample:Clone()
	newKill.Parent = killFrame
	newKill.Visible = true

	newKill.Position = UDim2.new(0.676, 0, 0.008, 0)

	local information = newKill.Information
	information.Text = target .. " was killed by " .. killer

	local killerImage = newKill.KillerImage
	killerImage.Image = image

	task.wait(10)
	
	local tween = ts:Create(newKill, TweenInfo.new(1), { 
		Position = newKill.Position + UDim2.new(2, 0, 0.008, 0) 
	})

	tween:Play()
	
	tween.Completed:Connect(function()
		newKill:Destroy()
	end)
end)

Also i’ve tinkered around with the positions and sizes of the Gui to make it more friendly for players with bigger and smaller screens, hope you don’t mind.

NewGui.rbxm (8.3 KB)

Here are some videos to show what i mean:

Even if you don’t like the sizes or positions, you can now just resize or reposition them and they’ll still be able to adapt to all screen sizes.

I hope this helps.

1 Like

This works brilliantly, thank you so much for the help :+1:
I never was really good at ui, especially getting them to stay in one spot

Happy to help!

Also, to make gui adapt to screen sizes you can set both the position and size of the ui element to {0.5, 0},{0.5, 0} for example and then re-scale and re-position it to however you want it to be, they’ll adapt by themselves.

The first numbers (0.5-s) stand for scale (basically for any screensize) and the last numbers (the 0-s) stand for offset, which does the offsetting and scaling in pixels instead of.

atleast i think thats what they mean.