Code review on gui script

  • What does the code do and what are you not satisfied with?
    This code in local script is used to control the elements in a ScreenGUI. it uses tweens for some visual effects. I feel like some improvements can be made in terms reducing its length and improving performance.
  • What potential improvements have you considered?
    putting tween:Play() right beside the tween declarations should help slightly. Some task.spawns would do good in my opinion.
  • How (specifically) do you want to improve the code?
    I want to make the code shorter as I think it uses too many lines unnecessarily. I also want to improve performance(if possible).
--parented under screen gui alongside 3 frames containing their elements .
local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TweenService")

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local hum = character:FindFirstChildOfClass("Humanoid")

local msg = RS.Events.msg
local waves = require(RS.Waves)

local gui = script.Parent
local hp = gui.HealthBar
local waveMsg = gui.WaveMessage
local notification = gui.Notification
local notifMsg = script.Notif

local function updateHealth()
	if hum:GetState() == Enum.HumanoidStateType.Dead then return; end
	local tweenInfo = TweenInfo.new(0.5)
	local percent = (hum.Health/hum.MaxHealth)
	local tween1 = TS:Create(hp.Bar, tweenInfo, {Position = UDim2.fromScale(percent, 0.5)})
	local tween2 = TS:Create(hp.Bar.Fill, tweenInfo, {Position = UDim2.fromScale(1 - percent, 0.5)})
	tween1:Play()
	tween2:Play()
	tween1.Completed:Once(function() tween1:Destroy() end)
	tween2.Completed:Once(function() tween2:Destroy() end)
	
	hp.Amount.Text = string.format("%.2f", tostring(hum.Health)) .. "%"
end

hum.HealthChanged:Connect(function()
	updateHealth()
end)

msg.OnClientEvent:Connect(function(msgType:number, arg1, arg2)
	if msgType == 1 then
		local waveType = waves[arg1].IsBoss == true and "Boss" or "Wave"
		waveMsg.MainText.Text = waveType .. " " .. arg1
		waveMsg.SubText.Text = waves[arg1].WaveMsg
		
		local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false)
		local tween1 = TS:Create(waveMsg.MainText, tweenInfo, {TextTransparency = 0})
		local tween2 = TS:Create(waveMsg.SubText, tweenInfo, {TextTransparency = 0})
		tween1:Play()
		tween2:Play()
		tween1.Completed:Once(function() tween1:Destroy(); end)
		tween2.Completed:Once(function() tween2:Destroy(); end)
		task.wait(4)
		local tween1 = TS:Create(waveMsg.MainText, tweenInfo, {TextTransparency = 1})
		local tween2 = TS:Create(waveMsg.SubText, tweenInfo, {TextTransparency = 1})
		tween1:Play()
		tween2:Play()
		tween1.Completed:Once(function() tween1:Destroy(); end)
		tween2.Completed:Once(function() tween2:Destroy(); end)
	elseif msgType == 2 then
		local clone = notifMsg:Clone()
		clone.Parent = notification
		clone.Message.Text = arg1
		clone.Icon.Image = arg2 or "rbxasset://textures/ui/GuiImagePlaceholder.png"
		
		task.wait(2)
		local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false)
		local tween1 = TS:Create(clone.Message, tweenInfo, {TextTransparency = 1})
		local tween2 = TS:Create(clone.Icon, tweenInfo, {ImageTransparency = 1})
		tween1:Play()
		tween2:Play()
		tween1.Completed:Once(function() tween1:Destroy(); end)
		tween2.Completed:Once(function() tween2:Destroy(); end)
		task.wait(5)
		clone:Destroy()
	end
end)

updateHealth()
game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)
2 Likes

oh my sparks, so many repeats!
Can you explain what every UI does?

also why are you cloning notifmsg?
Can’t you use the original?

Can I see how it looks like in game?

Sure thing.

  • Green bar with percentage is health indicator.
  • Wave 1 and the subtext below it makes up the wave message frame.
  • The You are being targeted by sniper lel (its just an example + ignore the highlights) is a notification thing so let you know things like a boss spawned, someone died etc. there are multiple Notification that are expected through out the match so notifMsg is used a template and cloned. The contents of the clone are then modified to convey the message.

btw sorry for the late reply.

local tween1 = TS:Create(hp.Bar, tweenInfo, {Position = UDim2.fromScale(percent, 0.5)})

why are you tweening two things?
Is there a green fill and the bar is the red background or…
why are you setting two things?

So I tried to shorten it a bit, using a function, and deleting redundant lines, what do you think?

--parented under screen gui alongside 3 frames containing their elements .
local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TweenService")

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local hum = character:FindFirstChildOfClass("Humanoid")

local msg = RS.Events.msg
local waves = require(RS.Waves)

local gui = script.Parent
local hp = gui.HealthBar
local waveMsg = gui.WaveMessage
local notification = gui.Notification
local notifMsg = script.Notif

local UITweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear)--the rest is default values
local DelayInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 2)

local function TweenWave(show: boolean)
	local goal = show and 0 or 1
	
	local tween1 = TS:Create(waveMsg.MainText, UITweenInfo, {TextTransparency = goal})
	local tween2 = TS:Create(waveMsg.SubText, UITweenInfo, {TextTransparency = goal})
	tween1:Play()
	tween2:Play()
	
	if not show then return end
	task.wait(4)
	TweenWave(false)
end

hum.HealthChanged:Connect(function(health)
	--no need to check for that...
	local tweenInfo = TweenInfo.new(0.5)
	local percent = health/hum.MaxHealth
	
	local tween1 = TS:Create(hp.Bar, tweenInfo, {Position = UDim2.fromScale(percent, 0.5)})
	local tween2 = TS:Create(hp.Bar.Fill, tweenInfo, {Position = UDim2.fromScale(1 - percent, 0.5)})
	tween1:Play()
	tween2:Play()

	hp.Amount.Text = string.format("%.1f%%", tostring(health))--eg: 95.0%
end)

msg.OnClientEvent:Connect(function(msgType:number, arg1, arg2)
	if msgType == 1 then
		local waveType = waves[arg1].IsBoss == true and "Boss" or "Wave"
		waveMsg.MainText.Text = waveType .. " " .. arg1
		waveMsg.SubText.Text = waves[arg1].WaveMsg

		TweenWave(true)
	elseif msgType == 2 then
		local clone = notifMsg:Clone()
		clone.Message.Text = arg1
		clone.Icon.Image = arg2 or "rbxasset://textures/ui/GuiImagePlaceholder.png"
		clone.Parent = notification--for optimization, parent should be set last

		local tween1 = TS:Create(clone.Message, DelayInfo, {TextTransparency = 1})
		local tween2 = TS:Create(clone.Icon, DelayInfo, {ImageTransparency = 1})
		tween1:Play()
		tween2:Play()
		
		task.wait(5)
		clone:Destroy()
	end
end)
--unless your healthbar in studio says 0% this isn't needed
game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)
1 Like

once for an invisible frame parented under the gui, once for the actual fill inside the invisible frame.