How do you constantly recognize the distance between the enemy and the player? URGENT

Script:

local npc = script.Parent
local debounce = false
local folder = script.Parent:WaitForChild("Information")

npc.Humanoid.Touched:Connect(function(hit) -- DAMAGING PLAYER
	if hit and game.Players:GetPlayerFromCharacter(hit.Parent) and folder.Attacks.Value == true then
		if debounce == false then
			debounce = true
			hit.Parent.Humanoid:TakeDamage(10) -- U SHOULD TO CHANGE THIS!!!
			wait(.25) -- AND THIS!!!
			debounce = false
		end
	end
end)

function FindPlayer(Position)
	local playerList = game:GetService("Players"):GetPlayers()	
	local torso = nil
	local distance = 30 -- CHANGE THIS TOO!!!
	local HRP = nil
	local humanoid = nil
	local player = nil
	
	for i, plr in pairs(playerList) do
		local playerCharacter = plr.Character or plr.CharacterAdded:Wait()
		if playerCharacter then
			HRP = playerCharacter:FindFirstChild("HumanoidRootPart")
			humanoid = playerCharacter:FindFirstChild("Humanoid")
			
			if (HRP ~= nil) and (humanoid ~= nil) and (humanoid.Health > 0) then
				
				if (HRP.Position - Position).Magnitude < distance then
					torso = HRP
					distance = (HRP.Position - Position).Magnitude
					print(distance)
					folder.Distance.Value = distance -- CHANGING DISTANCE!!!
				end
			end
		end
	end
	
	return torso
end

while wait(1) do
	local target = FindPlayer(script.Parent.HumanoidRootPart.Position)
	
	npc.Humanoid.Health = 100 -- DELETE THIS LATER
	if target ~= nil then
		script.Parent.Humanoid:MoveTo(target.Position, target) -- MOVING NPC TO US
	end
end

The main thing in my code at the moment is to write to IntValue what the distance between the npcs and the player is.

But, the problem I have is that after reaching the distance limit(30) the counter is not updated and my code breaks.

Question how to make the counter is constantly updated? So that the distance between the enemy and the player is constantly recorded in IntValue?

1 Like

Iā€™m assuming that the issue you are facing is that once a player reaches a specific distance to the NPC, the NPC will only chase after players that are in range of the new distance.

To solve this, you will need to create a separate variable, i.e. nearestPlayerDistance, to record down the closest distance; you should give this the same value as the variable distance as default.

After that, you will need to include a check to make sure that a player is within the distance of the variable distance, in this case 30. When a player is within range, you need to check whether their distance is less than the previous closest distance; and set their distance as the value for nearestPlayerDistance if so.

The logic behind this:

  • Iterate onto a player
  • Are they in range of the NPC?
  • If so, are they closer than the previous nearest player?
  • If so, make them the new nearest player
  • Return the new nearest player, so the NPC can chase after them
  • Repeat the iteration onto the next player

I have previously faced this same issue before, and I have provided an example script of how I have solved this. Use it as a guide for implementing it into your own NPC system.

function npcFuncs.nearestPlr(npcHumRoot, npcHum, detectRange)
	
	local inRange = false
	local nearestPlayerCharacter = nil
	local nearestPlayer = nil
	local nearestDistance = detectRange
	
	local playerList = Players:GetPlayers()
	
	for i, plr in pairs(playerList) do

		local plrCharacter = plr.Character or plr.CharacterAdded:Wait()
		
		local plrDistance = plr:DistanceFromCharacter(npcHumRoot.Position)
		
		if plrDistance <= detectRange then
			
			if plrDistance < nearestDistance then
				
				nearestPlayerCharacter = plrCharacter
				nearestPlayer = plr
				nearestDistance = plrDistance
				
			end
			
			inRange = true
			
		end
			
	end
	
	return inRange, nearestPlayerCharacter, nearestPlayer, nearestDistance
	
end
2 Likes
local npc = script.Parent
local debounce = false
local folder = script.Parent:WaitForChild("Information")
local Players = game:GetService("Players")

npc.Humanoid.Touched:Connect(function(hit) -- DAMAGING PLAYER
	if hit and game.Players:GetPlayerFromCharacter(hit.Parent) and folder.Attacks.Value == true then
		if debounce == false then
			debounce = true
			hit.Parent.Humanoid:TakeDamage(10) -- U SHOULD TO CHANGE THIS!!!
			wait(.25) -- AND THIS!!!
			debounce = false
		end
	end
end)

function FindPlayer(Position)
	local playerList = game:GetService("Players"):GetPlayers()	
	local torso = nil
	local distance = 0 -- CHANGE THIS TOO!!!
	local HRP = nil
	local humanoid = nil
	local player = nil
	
	for i, plr in pairs(playerList) do
		local playerCharacter = plr.Character or plr.CharacterAdded:Wait()
		if playerCharacter then
			HRP = playerCharacter:FindFirstChild("HumanoidRootPart")
			humanoid = playerCharacter:FindFirstChild("Humanoid")
			
			if (HRP ~= nil) and (humanoid ~= nil) and (humanoid.Health > 0) then
				
				if (HRP.Position - Position).Magnitude < distance then
					torso = HRP
				end
			end
		end
	end
	
	return torso
end

function nearestPlr(npcHumRoot, npcHum, detectRange, Position)

	local inRange = false
	local nearestPlayerCharacter = nil
	local nearestPlayer = nil
	local nearestDistance = detectRange
	local HRP = nil
	local humanoid = nil
	local distance = 30

	local playerList = Players:GetPlayers()

	for i, plr in pairs(playerList) do

		local plrCharacter = plr.Character or plr.CharacterAdded:Wait()

		local plrDistance = plr:DistanceFromCharacter(npcHumRoot.Position)
		
		HRP = plrCharacter:FindFirstChild("HumanoidRootPart")
		humanoid = plrCharacter:FindFirstChild("Humanoid")

		if plrDistance <= detectRange then

			if plrDistance < nearestDistance then

				nearestPlayerCharacter = plrCharacter
				nearestPlayer = plr
				nearestDistance = plrDistance
				
				distance = (HRP.Position - Position).Magnitude
				print(distance)
				folder.Distance.Value = distance -- CHANGING DISTANCE!!!
			end

			inRange = true

		end

	end

	return inRange, nearestPlayerCharacter, nearestPlayer, nearestDistance

end

while wait(1) do
	local target = FindPlayer(script.Parent.HumanoidRootPart.Position)
	nearestPlr()
	
	npc.Humanoid.Health = 100 -- DELETE THIS LATER
	if target ~= nil then
		script.Parent.Humanoid:MoveTo(target.Position, target) -- MOVING NPC TO US
	end
end

Like this? I pasted your code into mine, but is it just me or did I do something wrong?

1 Like

The logic in my previous post has to be implemented within your FindPlayer function. Additionally, the script that I have provided is just an example of how I personally have managed to implement the logic:

You should use the script as a reference for adding the logic into your FindPlayer function. My script will not work with your system because it was designed for my system, instead you should use it as an idea of how to implement that logic into your own system.