How would I detect if NPC is close to a huge model?

The NPC would only detect the center of the part position but I want the NPC to stop a certain distance away from a huge model.

local RunService = game:GetService("RunService")

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local WalkSpeed = humanoid.WalkSpeed

local castles = workspace:WaitForChild("Castles")

local damage = 5
local range = 10

local damageDebounce = false
local damageCooldown = 0.5

local loopConnection

local function nearestTarget()
	local maxDistance = 10000
	local nearesttarget = nil
	
	for i,v in ipairs(castles:GetChildren()) do
		local health = v:GetAttribute("Health")
		local maxHealth = v:GetAttribute("MaxHealth")
		local hitbox = v:FindFirstChild("Hitbox")
		
		if health and maxHealth and hitbox then
			local distance = (character.PrimaryPart.Position - hitbox.Position).Magnitude
			
			print(distance)
			
			if health <= 0 then
				nearesttarget = nil
			end
			
			if distance <= maxDistance and health > 0 then
				nearesttarget = hitbox
				maxDistance = distance
			end

			if distance <= range then
				humanoid.WalkSpeed = 0
				coroutine.wrap(function()
					if not damageDebounce then
						damageDebounce = true
						v:SetAttribute("Health", health - damage)
						task.wait(damageCooldown)
						damageDebounce = false
					end
				end)()
			else
				humanoid.WalkSpeed = WalkSpeed
			end
		end
	end
	return nearesttarget
end

loopConnection = RunService.Heartbeat:Connect(function()
	local target = nearestTarget()
	
	if target then
		humanoid:MoveTo(target.Position)
	end
	
	if humanoid.Health <= 0 and loopConnection then
		loopConnection:Disconnect()
	end
end)
local distance = (character.PrimaryPart.Position - part.Position).Magnitude

Mainly about this part.


The target is the castle. The NPC does not stop a certain distance from it.

You would probably be better off using a raycast.

Wow. I didn’t think of that, I will try this.

1 Like

Thanks! I got it to work!

local function castRay(target)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {character}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.IgnoreWater = true
	
	local rayOrigin = character.PrimaryPart.Position
	local rayDestination = target.Position
	local rayDirection = (rayDestination - rayOrigin)
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		local distance = math.floor(raycastResult.Distance)
		if distance <= range then
			return true
		else
			return false
		end
	end
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.