PcoWSkbVqDnWTu_dm2ix
Creating a Health Pickup
Part 2 - Connecting the Pickups
Creating a Health Pickup
Part 2 - Connecting the Pickups

Looping with ipairs

onTouchHealthPickup needs to be called for each health pickup in the array. To do this efficiently, a new kind of loop syntax will be used.

ipairs is a function that can be used with a for loop to go through each element of an array. You do not need to specify where the loop begins and ends. A for loop using ipairs is defined as follows:

  • Index: this is equivalent to the control variable in a regular for loop.
  • Value: this will be populated with each element in the array as the loop iterates. It’s a good idea to name the value variable after what it will actually contain.
  • Array: the array you want to iterate over is passed to the ipairs function.

In the example below, you don’t need the index for anything, so it can be left blank with _.

  • Create a for loop using the ipairs function, passing healthPickups.
local function onTouchHealthPickup(otherPart, healthPickup)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
        humanoid.Health = MAX_HEALTH
    end
end

for _, healthPickup in ipairs(healthPickups) do

end

A wrapper function will be needed to pass the health pickup to the onTouchHealthPickup function when connecting to the Touched event.

  1. In the for loop, connect the Touched event to an anonymous function with a parameter called otherPart.

  2. Call the onTouchHealthPickups function, passing both the otherPart parameter and the healthPickup.

    for _, healthPickup in ipairs(healthPickups) do
        healthPickup.Touched:Connect(function(otherPart)
        	onTouchHealthPickup(otherPart, healthPickup)
        end)
    end

Test your code now and you should find that the health pickup restores your health. You will need to damage your player first - try standing on the vent next to the spawn point.

Steaming vent in example world to the right of the spawn point

A health bar should appear in the top right which will disappear when the player is healed.

Pickup Cooldown

Currently, the pickup will indefinitely heal any player who touches it. It would be more effective in a game if it could only be picked up once, with a short cooldown before it can be used again.

First, you need to record whether or not the pickup is in the cooldown period. The pattern below should be familiar from Fading Trap - this time, the debounce will be achieved by setting an attribute on the health pickup.

  1. In the for loop, set a new attribute called “Enabled” to true.

  2. Wrap the code inside onTouchHealthPickup in an if statement with the condition healthPickup:GetAttribute("Enabled").

    local function onTouchHealthPickup(otherPart, healthPickup)
    	if healthPickup:GetAttribute("Enabled") then
            local character = otherPart.Parent
            local humanoid = character:FindFirstChildWhichIsA("Humanoid")
            if humanoid then
                humanoid.Health = MAX_HEALTH
            end
    	end
    end
    
    for _, healthPickup in ipairs(healthPickups) do
        healthPickup:SetAttribute("Enabled", true)
        healthPickup.Touched:Connect(function(otherPart)
            onTouchHealthPickup(otherPart, healthPickup)
        end)
    end

Disabling the Pickup

The pickup should provide visual feedback that it is disabled - a common way to indicate this is to make it slightly transparent.

  1. Declare three constants at the top of the script:

    • ENABLED_TRANSPARENCY = 0.4
    • DISABLED_TRANSPARENCY = 0.9
    • COOLDOWN = 20 (you may wish to shorten this when testing)
    local MAX_HEALTH = 100
    local ENABLED_TRANSPARENCY = 0.4
    local DISABLED_TRANSPARENCY = 0.9
    local COOLDOWN = 20
    
    local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
  2. In the if statement in onTouchHealthPickup, set the BasePart/Transparency|Transparency of the pickup to DISABLED_TRANSPARENCY, and the value of the Enabled attribute to false.

    local function onTouchHealthPickup(otherPart, healthPickup)
    	if healthPickup:GetAttribute("Enabled") then 
    		local character = otherPart.Parent
    		local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    		if humanoid then
    			humanoid.Health = MAX_HEALTH
    			healthPickup.Transparency = DISABLED_TRANSPARENCY
    			healthPickup:SetAttribute("Enabled", false)
    		end
    	end
    end
  3. Call the wait function, passing COOLDOWN.

  4. Set Transparency back to ENABLED_TRANSPARENCY and Enabled back to true.

    local function onTouchHealthPickup(otherPart, healthPickup)
    	if healthPickup:GetAttribute("Enabled") then 
    		local character = otherPart.Parent
    		local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    		if humanoid then
    			humanoid.Health = MAX_HEALTH
    			healthPickup.Transparency = DISABLED_TRANSPARENCY
    			healthPickup:SetAttribute("Enabled", false)
    			wait(COOLDOWN)
    			healthPickup.Transparency = ENABLED_TRANSPARENCY
    			healthPickup:SetAttribute("Enabled", true)
    		end
    	end
    end

Test your pickup again: you should find that when you touch the pickup it restores your health, goes transparent, then comes back ready to be used again.

If you want to make the feedback more impactful for the player when the pickup is collected, try cutting the brightness of the PointLight in the pickup when you change the transparency.

Try using these health pickups in your own projects, or change the appearance and effect to give a different kind of power-up to your players.

local MAX_HEALTH = 100
local ENABLED_TRANSPARENCY = 0.4
local DISABLED_TRANSPARENCY = 0.9
local COOLDOWN = 20

local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
local healthPickups = healthPickupsFolder:GetChildren()

local function onTouchHealthPickup(otherPart, healthPickup)
	if healthPickup:GetAttribute("Enabled") then 
		local character = otherPart.Parent
		local humanoid = character:FindFirstChildWhichIsA("Humanoid")
		if humanoid then
			humanoid.Health = MAX_HEALTH
			healthPickup.Transparency = DISABLED_TRANSPARENCY
			healthPickup:SetAttribute("Enabled", false)
			wait(COOLDOWN)
			healthPickup.Transparency = ENABLED_TRANSPARENCY
			healthPickup:SetAttribute("Enabled", true)
		end
	end
end

for _, healthPickup in ipairs(healthPickups) do
	healthPickup:SetAttribute("Enabled", true)
	healthPickup.Touched:Connect(function(otherPart)
		onTouchHealthPickup(otherPart, healthPickup)
	end)
end


Previous Page Getting Started