Script not giving closest player money?

Hello, I’ve been trying for a while now to create a quest in which a player has to kill an enemy NPC.
The problem is that it’s not working, and it’s not giving errors either. It’s also not setting the value ‘questdone’ to true.
Script:

local Humanoid = script.Parent.Humanoid

Humanoid.Died:Connect(function()
	local quest = script.Parent.VampirePrincessQuest
	local questdone = script.Parent.PitchForkQuestFinished
	if quest.Value ~= nil then
		questdone.Value = true
		if questdone.Value == true then
			for i, v in pairs(game.Players:GetPlayers()) do
				local magnitude = (script.Parent.HumanoidRootPart.Position - v.Character.HumanoidRootPart.Position).Magnitude
				local mag = math.huge
				local target
				if magnitude < mag then
					mag = magnitude
					target = v
					target.leaderstats.Money.Value = target.leaderstats.Money.Value + 100
				end
			end
		end
	end
end)

I am getting the player in range since I have no clue how to get the specific player.

Position is not the right thing to use for HumanoidRootPart as it doesn’t update the position. Instead, use HumanoidRootPart.CFrame which is the actual position of it. This would be the script:

local Humanoid = script.Parent.Humanoid

Humanoid.Died:Connect(function()
	local quest = script.Parent.VampirePrincessQuest
	local questdone = script.Parent.PitchForkQuestFinished
	if quest.Value ~= nil then
		questdone.Value = true
		if questdone.Value == true then
			for i, v in pairs(game.Players:GetPlayers()) do
				local magnitude = (script.Parent.HumanoidRootPart.CFrame- v.Character.HumanoidRootPart.CFrame).Magnitude --Only changed this line
				local mag = math.huge
				local target
				if magnitude < mag then
					mag = magnitude
					target = v
					target.leaderstats.Money.Value = target.leaderstats.Money.Value + 100
				end
			end
		end
	end
end)
2 Likes

Getting the same result when I use CFrame

A few things.

First the questdone.Value conditional.

Since you’re setting questdone.Value to be true on the line above it, there’s no need to check if it’s true. It has to be true because you just set it to true.

This is not how you resolve magnitude.


A - B results in a new vector who’s head points towards A when it’s origin is placed at B. You need to use the Position component of those CFrame’s to resolve this new vector.

local magnitude = (script.Parent.HumanoidRootPart.CFrame.Position - v.Character.HumanoidRootPart.CFrame.Position).Magnitude

Lastly, your loop to find the nearest player character is a bit off. You want to declare the smallest magnitude and target outside of the loop, then loop thru all characters so you can compare the current character’s magnitude against the shortest known magnitude.

A function for finding the nearest player character that should help clarify the logic:

local function getNearestPlayerCharacter(position)
    local nearestPlayer = nil
    local lowestMagnitude = math.huge

    for _, player in ipairs(game.Players:GetPlayers()) do
        if not player.Character then continue end -- prevent erroring on player's who don't currently have a character

        local differenceVector = position - player.Character.HumanoidRootPart.CFrame.Position -- make our new vector

        if differenceVector.Magnitude < lowestMagnitude then --update variables if shorter than lowestMagnitude
            lowestMagnitude = differenceVector.Magnitude
            nearestPlayer = player
        end
    end

    return nearestPlayer
end
2 Likes

Alternatively, I’ve found Player | Roblox Creator Documentation to be an incredibly useful function on cutting down lines for distance checks.