Character cannot move when knocked down

I’m having an issue where, after a player is knocked down, they are unable to move. When they get revived, they stand up but still can’t move, and the character ends up falling flat on the ground. Any help would be greatly appreciated!

local Players = game:GetService("Players")

local MIN_HEALTH = 30 -- Health at which the player will get back up
local REGEN_RATE = 1 -- Amount of health regained per second
local REGEN_INTERVAL = 3 -- Time interval for regeneration (seconds)
local TIME_UNTIL_DEATH = 45 -- How long the player has before dying when knocked

local ReviveBillboardGui = script:WaitForChild("ReviveBillboardGui")


local function applyAlignOrientation(humanoidRootPart: BasePart)
	if humanoidRootPart:FindFirstChild("DownedAlignOrientation") then return end

	local attachment = Instance.new("Attachment")
	attachment.Name = "UprightAttachment"
	attachment.Parent = humanoidRootPart

	local align = Instance.new("AlignOrientation")
	align.Name = "DownedAlignOrientation"
	align.Attachment0 = attachment
	align.RigidityEnabled = true
	align.Mode = Enum.OrientationAlignmentMode.OneAttachment
	align.MaxTorque = math.huge
	align.Responsiveness = 200
	align.CFrame = CFrame.Angles(0, 0, 0)
	align.Parent = humanoidRootPart
end

local function removeAlignOrientation(humanoidRootPart: BasePart)
	local align = humanoidRootPart:FindFirstChild("DownedAlignOrientation")
	local attachment = humanoidRootPart:FindFirstChild("UprightAttachment")
	if align then align:Destroy() end
	if attachment then attachment:Destroy() end
end


local function whenKnocked(character)
	local head = character:WaitForChild("Head")
	local humanoid = character:WaitForChild("Humanoid")
	local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
	print(humanoid:GetState())
	-- Adjust movement properties
	humanoid.WalkSpeed = 4
	humanoid.JumpHeight = 0
	humanoid.AutoRotate = false
	humanoid.HipHeight = -0.4
	humanoid.CameraOffset = Vector3.new(0, -1.1, 0)


	humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
	humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
	print(humanoid:GetState())
	-- Force upright
	applyAlignOrientation(humanoidRootPart)

	-- Billboard UI
	local billboardClone = ReviveBillboardGui:Clone()
	billboardClone.Adornee = head
	billboardClone.Parent = head
end


function whenRevived(character)
	local humanoid:Humanoid = character:WaitForChild("Humanoid")
	local head = character:WaitForChild("Head")
	local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
	print(humanoid:GetState())
	-- Clean up revive UI
	local billboardClone = head:FindFirstChild("ReviveBillboardGui")
	if billboardClone then
		billboardClone:Destroy()
	end

	-- Reset values
	humanoid.HipHeight = 2
	humanoid.CameraOffset = Vector3.new(0, 0, 0)
	humanoid.AutoRotate = true
	humanoid.WalkSpeed = 16
	humanoid.JumpHeight = 7.2
	humanoid.PlatformStand = false

	removeAlignOrientation(humanoidRootPart)

	-- Force a proper humanoid state
	task.defer(function()
		humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		task.wait(0.1)
		humanoid:ChangeState(Enum.HumanoidStateType.Running)
	end)

	print("Humanoid revived and state reset.")
	print(humanoid:GetState())
end

local function whenDied(player)
	print(player.Name .. " has died.")
	-- Handle final death logic, stats, respawn, etc.
	-- player:LoadCharacter()
end

local function createPrompt(parent, name)
	local prompt = Instance.new("ProximityPrompt")
	prompt.MaxActivationDistance = 10
	prompt.HoldDuration = 1
	prompt.ActionText = "Revive " .. name
	prompt.Name = "RevivePrompt"
	prompt.RequiresLineOfSight = false
	prompt.Parent = parent
	return prompt
end

local function handleCharacter(character: Model, name: string)
	local characterValuesFolder = character:WaitForChild("CharacterValues")
	local downedValue = characterValuesFolder:WaitForChild("Downed")

	
	local humanoid: Humanoid = character:WaitForChild("Humanoid")
	local rootPart = character:WaitForChild("HumanoidRootPart")
	humanoid.BreakJointsOnDeath = false
	humanoid.RequiresNeck = false
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)

	local player = Players:GetPlayerFromCharacter(character)

	local isKnocked = false
	print(humanoid:GetState())
	humanoid.HealthChanged:Connect(function(health)
		-- If knocked, prevent health from dropping below 0 (so no damage can kill)
		if isKnocked then
			if health < 0 then
				humanoid.Health = 0
				return
			end
		end

		if health <= 0 and humanoid:GetState() ~= Enum.HumanoidStateType.Dead and not isKnocked then
			isKnocked = true -- Player just got knocked
			downedValue.Value = true
			print(humanoid:GetState())
			whenKnocked(character)

			local revivePrompt = createPrompt(rootPart, name)
			local isRevived = false

			local deathTimer = TIME_UNTIL_DEATH
			task.spawn(function()
				while deathTimer > 0 and humanoid.Health <= 0 and humanoid.Parent and not isRevived do
					task.wait(1)
					deathTimer -= 1
				end

				if not isRevived and humanoid.Health <= 0 then
					whenDied(player)
				end
			end)

			revivePrompt.Triggered:Connect(function(triggeringPlayer)
				if humanoid.Health <= 0 then
					isRevived = true
					isKnocked = false -- Player is no longer knocked
					revivePrompt:Destroy()
					humanoid.Health = MIN_HEALTH
					downedValue.Value = false
					whenRevived(character)
				end
			end)
			
			revivePrompt.TriggerEnded:Connect(function(triggeringPlayer)
				
			end)
		end
	end)
end


local function handlePlayer(player: Player)
	local function onCharacterAdded(character)
		handleCharacter(character, player.Name)
	end

	if player.Character then
		onCharacterAdded(player.Character)
		
	end
	player.CharacterAdded:Connect(onCharacterAdded)
end

-- Setup for current and future players
for _, player in ipairs(Players:GetPlayers()) do
	handlePlayer(player)
end
Players.PlayerAdded:Connect(handlePlayer)

1 Like

respawn character when you revive it, its not possible to revive humanoid after it got 0 health, as alternative you can make own Health system

or you can just clamp the humanoid’s health so it’s not at 0 but stays at something like 5

I tested the parts of your code for reviving, and I found a problem, once the character is revived, it stands rigid and you can’t move which is what I think your problem is
My code to recreate:

task.wait(5)

local charName = game.Players:GetPlayers()[1].Name
local h = workspace:WaitForChild(charName):WaitForChild("Humanoid")

--server
warn("set")
h.BreakJointsOnDeath = false
h.RequiresNeck = false

--This prevents auto respawn
h:SetStateEnabled(Enum.HumanoidStateType.Dead, false)

warn("killing")

h.Health = 0

warn("ok needs revive now")

task.wait(1)
warn("reviving")
h.Health = h.MaxHealth
h:ChangeState(Enum.HumanoidStateType.Running)

After the reviving section what happens is on the server, the state is set to Running, but on the client, the state is still Dead, and get the rigid issue, if you do changestate to Running using the client’s command bar, you can walk again:

local h = workspace.GalaxyRIP324.Humanoid h:ChangeState(Enum.HumanoidStateType.Running) task.wait(0.5) print(h:GetState())

Anyway this is bunch of yap

Heres what I would try:

  1. put this in a localscript in StarterCharacterScripts
script.Parent.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)

This prevents the character on the client from going into the Dead state, I think it should work with your script well
2. If #1 doesnt work Make a remoteevent that fires the client in your revive function, and change the state of the humanoid there to Running

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