Attempt to index nil with 'GetAttribute'

I’d like to negate damage when the player has the IsBlockingRight or IsBlockingLeft attributes enabled, but whenever I try to check if the attributes are enabled in the script it always comes up with “attempt to index nil”. I’ve tried to do this with a separate function and couldn’t get that to work.

Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

-- Global variable for the targeted player
local targetedPlayer = nil

local function DealDamage(player, damage)
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChild("Humanoid")
		if humanoid then
			humanoid.Health = humanoid.Health - damage
			print(damage)
		end
	end
end

local function GetDamageForPunchType(punchType)
	if punchType == "LeftPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(3, 8)
	elseif punchType == "RightPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(10, 25)
	else
		return 0
	end
end

local function GetNearestPlayer(position, maxDistance)
	local players = Players:GetPlayers()
	local nearestPlayer
	local shortestDistance = maxDistance

	for _, player in pairs(players) do
		local character = player.Character
		if character and character:FindFirstChild("Humanoid") then
			local distance = (position - character:WaitForChild("Humanoid").Parent.PrimaryPart.Position).Magnitude

			if distance < shortestDistance then
				nearestPlayer = player
				shortestDistance = distance
			end
		end
	end

	-- Set the targetedPlayer global variable here
	targetedPlayer = nearestPlayer

	return nearestPlayer
end

local function ThrowPunch(npc, actionName, animationId)
	local Remote = ReplicatedStorage:WaitForChild(actionName .. "Remote")
	local Animation = Instance.new("Animation")
	Animation.AnimationId = animationId

	local damage = GetDamageForPunchType(actionName)  -- Get the damage for the specific punch type

	local function PlayPunch()
		local humanoid = npc:WaitForChild("Humanoid")
		local position = humanoid.Parent.PrimaryPart.Position
		local nearestPlayer = GetNearestPlayer(position, 5)

		if nearestPlayer then
			humanoid:LoadAnimation(Animation):Play()
			DealDamage(nearestPlayer, damage)
			Remote:InvokeClient(nearestPlayer)
		end
	end

	local function PunchLoop()
		while true do
			PlayPunch()
			wait(math.random(2, 6))  -- Wait for a break before the next punch
		end
	end

	-- Start the coroutine
	task.spawn(PunchLoop)
end

local npc = script.Parent

while wait(1) do
	local punchTypes = {
		{ type = "LeftPunch", animationId = "rbxassetid://15479380094" },
		{ type = "RightPunch", animationId = "rbxassetid://15476721938" }
	}

	local punchInfo = punchTypes[math.random(1, #punchTypes)]
	ThrowPunch(npc, punchInfo.type, punchInfo.animationId)
end

Error bit:

local function GetDamageForPunchType(punchType)
	if punchType == "LeftPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(3, 8)
	elseif punchType == "RightPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(10, 25)
	else
		return 0
	end
end
1 Like

The targetedPlayer global is nil when you call GetDamageForPunchType. You have to find the nearest player before calling it, so move the local damage = GetDamageForPunchType(actionName) line to

local function PlayPunch()
		local humanoid = npc:WaitForChild("Humanoid")
		local position = humanoid.Parent.PrimaryPart.Position
		local nearestPlayer = GetNearestPlayer(position, 5)

		if nearestPlayer then
			humanoid:LoadAnimation(Animation):Play()
            local damage = GetDamageForPunchType(actionName)
			DealDamage(nearestPlayer, damage)
			Remote:InvokeClient(nearestPlayer)
		end
	end
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

-- Global variable for the targeted player
local targetedPlayer

local function DealDamage(player, damage)
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChild("Humanoid")
		if humanoid then
			humanoid.Health -= damage
			print(damage)
		end
	end
end

local function GetDamageForPunchType(punchType)
    if not targetedPlayer then return 0 end
	if punchType == "LeftPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(3, 8)
	elseif punchType == "RightPunch" and targetedPlayer:GetAttribute("IsBlockingRight") == false then
		return math.random(10, 25)
	else
		return 0
	end
end

local function GetNearestPlayer(position, maxDistance)
	local players = Players:GetPlayers()
	local nearestPlayer
	local shortestDistance = maxDistance

	for _, player in players do
		local character = player.Character
		if character and character:FindFirstChild("Humanoid") then
			local distance = (position - character.PrimaryPart.Position).Magnitude

			if distance < shortestDistance then
				nearestPlayer = player
				shortestDistance = distance
			end
		end
	end

	-- Set the targetedPlayer global variable here
	targetedPlayer = nearestPlayer

	return nearestPlayer
end

local function ThrowPunch(npc, actionName, animationId)
	local Remote = ReplicatedStorage:WaitForChild(actionName .. "Remote")
	local Animation = Instance.new("Animation")
	Animation.AnimationId = animationId

	local function PlayPunch()
		local humanoid = npc:WaitForChild("Humanoid")
		local position = humanoid.Parent.PrimaryPart.Position
		local nearestPlayer = GetNearestPlayer(position, 5)

		if nearestPlayer then
            local damage = GetDamageForPunchType(actionName)  -- Get the damage for the specific punch type
			humanoid:LoadAnimation(Animation):Play()
			DealDamage(nearestPlayer, damage)
			Remote:InvokeClient(nearestPlayer)
		end
	end

	local function PunchLoop()
		while task.wait(Random.new():NextInteger(2, 6) do
			PlayPunch()
		end
	end

	-- Start the coroutine
	coroutine.wrap(PunchLoop)()
end

local npc = script.Parent

task.spawn(function()
    while task.wait(1) do
	    local punchTypes = {
		    LeftPunch = "rbxassetid://15479380094";
		    RightPunch = "rbxassetid://15476721938";
	    }

            local index = Random.new():NextInteger(1, #punchTypes)
            local i = 0
        for k, v in punchTypes do
            i += 1
            if i ~= index then continue end
	        ThrowPunch(npc, k, v)
            break
        end
    end
end)