Issues with a revive script

I have been working on a revive system for a while now. I have a few issues with it when I tested it. First of all the timer gets displayed on a “BillboardGui” through a local script and the countdown only shows for the player who is knocked. Second issue is that the coroutines (resume, yield) don’t seen to have any effect on the timer or maybe they aren’t functioning. Third issue: I have to trigger the Proximity Prompt twice for the player to get fully revived, the first trigger only stops the animation.
ServerScript (Named: ReviveServer):

game.Players.PlayerAdded:Connect(function(p)
	
	local RS = game:GetService("ReplicatedStorage")
	local BillboardGuiEvent = RS.RemoteEvents.BillboardGuiEvent
	local SS = game:GetService("ServerStorage")
	local Billboard = SS.BillboardGui
	
	local Timer = 30
	
	p.CharacterAdded:Connect(function(c)
		c:WaitForChild("Humanoid").HealthChanged:Connect(function(health)
			if health <= 1 and not c:FindFirstChild("Revived") then 
				
				c.Humanoid.MaxHealth = math.huge
				c.Humanoid.Health = math.huge
				
				c.HumanoidRootPart.Anchored = true
				
				local ClonedBB = Billboard:Clone()
				ClonedBB.Parent = c.Head
				
				local function startTimer()
					local remainingTime = Timer

					while remainingTime > 0 do
						BillboardGuiEvent:FireAllClients(remainingTime)
						wait(1)
						remainingTime -= 1
						if remainingTime <= 0 then
							c.Humanoid.Health = 0
							print("Timer ran out, Humanoid died")
							ClonedBB:Destroy()
						end
					end
				end
				
				local CoroutineTimer = coroutine.wrap(startTimer)
				CoroutineTimer()
				
				local proximityPrompt = Instance.new("ProximityPrompt")
				proximityPrompt.HoldDuration = 3
				proximityPrompt.ActionText = "Hold E to Revive"
				proximityPrompt.ObjectText = c.Name .. "'s corpse"
				proximityPrompt.RequiresLineOfSight = false
				proximityPrompt.Parent = c.HumanoidRootPart
				
				game.ReplicatedStorage:WaitForChild("ReviveRE"):FireClient(p, proximityPrompt)
				
				
				proximityPrompt.Triggered:Connect(function(plr)
					
					local revived = Instance.new("BoolValue", c)
					revived.Name = "Revived"
					
					proximityPrompt.Enabled = false
					proximityPrompt:Destroy()
					
					c.Humanoid.MaxHealth = 100
					c.Humanoid.Health = c.Humanoid.MaxHealth
					c.HumanoidRootPart.Anchored = false
					
					ClonedBB:Destroy()
					print("Revived the Humanoid and added a tag so they die the next time")
					
					coroutine.yield(CoroutineTimer())
					
					game.ReplicatedStorage:WaitForChild("ReviveRE"):FireClient(p)
				end)
				
				proximityPrompt.PromptButtonHoldBegan:Connect(function()
					coroutine.yield(CoroutineTimer())
					print("Timer Has Been Paused, Someone is reviving")
				end)
				proximityPrompt.PromptButtonHoldEnded:Connect(function()
					coroutine.resume(CoroutineTimer())
					print("Timer Has Been Resumed, Not Completed Hold")
				end)
				
				wait(20)
				
				if not c:FindFirstChild("Revived") then
					
					local revived = Instance.new("BoolValue", c)
					revived.Name = "Revived"
					
					c.Humanoid.Health = 0
					print("Humanoid died, already revived before")
				end
			end
		end)
	end)
end)

LocalScript (Named: ReviveClient):

local anim = script.Parent.Humanoid:LoadAnimation(script:WaitForChild("DeadAnimation"))

game.ReplicatedStorage:WaitForChild("ReviveRE").OnClientEvent:Connect(function(proximityPrompt)
	
	if proximityPrompt then
		
		proximityPrompt.Enabled = false
	
		anim:Play()

	else
	
		anim:Stop()
	end
end)

LocalScript inside of the “TextLabel” inside of the “BillboardGui” (Named: LocalScript):

local replicatedStorage = game:GetService("ReplicatedStorage")
local BillBoardGuiEvent = replicatedStorage.RemoteEvents.BillboardGuiEvent

local textlabel = script.Parent

BillBoardGuiEvent.OnClientEvent:Connect(function(remainingTime)
	textlabel.Text = tostring(remainingTime)
end)
1 Like
  1. The timer only displays for the player who is knocked:
    The reason for this is because you are firing the BillboardGuiEvent on all clients instead of just the client of the player who is knocked. You can fix this by changing BillboardGuiEvent:FireAllClients(remainingTime) to BillboardGuiEvent:FireClient(p, remainingTime) in the startTimer function.

  2. The coroutines (resume, yield) don’t seem to have any effect on the timer:
    The reason for this is because you are not using coroutine.yield or coroutine.resume properly. In the Triggered event of the proximityPrompt, you need to call coroutine.yield(CoroutineTimer) instead of coroutine.yield(CoroutineTimer()), and in the PromptButtonHoldBegan event, you need to call coroutine.resume(CoroutineTimer) instead of coroutine.resume(CoroutineTimer()).

  3. The Proximity Prompt needs to be triggered twice for the player to get fully revived:
    It seems like the issue here is that you are destroying the proximityPrompt too early. You should move the line proximityPrompt:Destroy() to after the coroutine has finished running.

3 Likes