PcoWSkbVqDnWTu_dm2ix
We use cookies on this site to enhance your user experience

Top Down Action: Health Packs

Top Down Action: Health Packs

Jul 30 2018, 2:22 PM PST 5 min

Exploration is a big part of the top-down action genre. One mechanic we can add to the game are health packs that the player has to find in the environment. The level already has some health pack models included inside the HealthPacks Folder inside the Workspace. To get these health packs to work we need to do two things: disable the default health regeneration of characters and bind a function to the health packs’ touched events to heal players on contact.

TDS_Healthpack.png

Disable Health Regen

When a player’s character is added to the game a Script is inserted automatically to regenerate the character’s health over time. This works for many game types, but for our game we want our player to only get healed if they find a health pack. Let’s add some code to remove this regeneration script after it is added. Add a new script called HealthPackManager to ServerStorage. Insert the following code:

local function onCharacterAdded(character)
	local healthScript = character:WaitForChild('Health')
	healthScript:Destroy()
end

local function onPlayerAdded(player)
	player.CharacterAdded:connect(onCharacterAdded)
end

game.Players.PlayerAdded:connect(onPlayerAdded)

In this script we define two functions: one to when the player joins the game and one to when a player’s character spawns. onCharacterAdded simply waits for a script called Health to be added to the character and then promptly destroys it, which stops that script from running. onPlayerAdded simply binds onCharacterAdded to the added player.

Heal Player

Now let’s add code to our script to cause the health packs to heal the player’s character on contact. Enter the following code:

local healAmount = 30

local function bindHealthPackTouched(healthPack)
	healthPack.Touched:connect(function(otherPart)
		local character = otherPart.Parent
		if character and game.Players:GetPlayerFromCharacter(character) then
			local humanoid = character:FindFirstChild('Humanoid')
			humanoid.Health = math.min(humanoid.Health + healAmount, humanoid.MaxHealth)
		end
	end)	
end

local function onCharacterAdded(character)
	local healthScript = character:WaitForChild('Health')
	healthScript:Destroy()
end

local function onPlayerAdded(player)
	player.CharacterAdded:connect(onCharacterAdded)
end

game.Players.PlayerAdded:connect(onPlayerAdded)

for _, healthPack in pairs(game.Workspace.HealthPacks:GetChildren()) do
	bindHealthPackTouched(healthPack)
end

Here we define the function bindHealthPackTouched, which takes a health pack as an argument. It then binds a function to the BasePart/Touched|Touched event of the passed in health pack. In this function, we first check if the touching part belongs to a player character. If so, we find that character’s humanoid and increase it’s health. We don’t want the health going over the maximum health of the character, so we use math.min when setting the health to either set the health to the current health + 30 or the maximum health, whichever is lower. Later in the script we loop through all of the health packs in the level and call bindHealthPackTouched with the health pack as the argument.

Right now there is no limit on the healing a player can get from a health pack. We need to add a few checks to make sure the health pack only triggers at appropriate times. We only want the health pack to heal players who have taken damage but haven’t been knocked out. We also want to consume the healthpack after it’s been used.

local healAmount = 30

local function bindHealthPackTouched(healthPack)
	healthPack.Touched:connect(function(otherPart)
		local character = otherPart.Parent
		if character and game.Players:GetPlayerFromCharacter(character) then
			local humanoid = character:FindFirstChild('Humanoid')
			if humanoid and humanoid.Health > 0 and humanoid.Health < humanoid.MaxHealth then
				humanoid.Health = math.min(humanoid.Health + healAmount, humanoid.MaxHealth)
				healthPack:Destroy()
			end
		end
	end)	
end

local function onCharacterAdded(character)
	local healthScript = character:WaitForChild('Health')
	healthScript:Destroy()
end

local function onPlayerAdded(player)
	player.CharacterAdded:connect(onCharacterAdded)
end

game.Players.PlayerAdded:connect(onPlayerAdded)

for _, healthPack in pairs(game.Workspace.HealthPacks:GetChildren()) do
	bindHealthPackTouched(healthPack)
end

Now when a healthpack is touched we check the health of the character’s humanoid; If it is between 1 and Humanoid/MaxHealth then we can proceed. We also call Instance/Destroy|Destroy on the healthpack after the heal to remove the pack so it can only be used once.