I have a script that gets a random target but I want it to get the closest target. What should I do to achieve that?
local currentTarget = nil
local npcs = workspace:WaitForChild("Npcs")
local function castRay(target)
if target.PrimaryPart ~= nil then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npcs}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.IgnoreWater = true
local rayOrigin = character.PrimaryPart.Position
local rayDestination = target.PrimaryPart.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
currentTarget = target
return true, raycastResult.Position, distance
end
end
end
currentTarget = nil
return false, nil, nil
end
local function findTarget()
local checkRay, position, distance = nil, nil, nil
for i,v in ipairs(npcs:GetChildren()) do
checkRay, position, distance = castRay(currentTarget or v)
if currentTarget ~= nil then
local savedTarget = currentTarget
local targetRoot = currentTarget.PrimaryPart
local human = currentTarget:FindFirstChildWhichIsA("Humanoid")
if human and human.Health > 0 then
if human and human.Health <= 0 then
currentTarget = nil
end
if distance > range then
currentTarget = nil
end
if player and targetRoot ~= nil and checkRay == true and distance <= attackRange then
local characterRoot = character.PrimaryPart
characterRoot.CFrame = CFrame.lookAt(characterRoot.Position, Vector3.new(position.X, characterRoot.Position.Y, position.Z))
end
end
end
end
end
To get the closest player you need to follow these steps:
local players = game.Players:GetChildren() -- this will make a table (list) of all the players in the game
local initialPos = humanoidRootPart.Position -- This would be the initial position in which you are comparing distances
local nearest,distance = players[1],9999999999999 -- This is some default values so we save time
for i,v in pairs(players) do --Repeat the same function for each player in the list
local magnitude = (v.Character.HumanoidRootPart.Position - initialPos).Magnitude -- This will get the distance between the current players character and the intial position we are comparing it with
if magnitude < distance then -- checking if the current players distance is smaller than the current best
nearest = v -- Setting the new better values if the player IS closer
distance = magnitude
end
end
print(nearest) -- nearest will be the nearest player, you can then get his character with: nearest.Character
If you dont want players, just change the list at the start with the list of npcs that you want to compare. Then remove all the player.Character since you already have the character in the list
local currentTarget = nil
local npcs = workspace:WaitForChild("Npcs")
local function castRay(target)
if target.PrimaryPart ~= nil then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npcs}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.IgnoreWater = true
local rayOrigin = character.PrimaryPart.Position
local rayDestination = target.PrimaryPart.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
currentTarget = target
return true, raycastResult.Position, distance
end
end
end
currentTarget = nil
return false, nil, nil
end
local function findTarget()
local checkRay, position, distance = nil, nil, nil
local nearestDistance = math.huge
for i,v in ipairs(npcs:GetChildren()) do
local targetRoot = v.PrimaryPart
local human = v:FindFirstChildWhichIsA("Humanoid")
if targetRoot ~= nil and human and human.Health > 0 then
checkRay, position, distance = castRay(currentTarget or v)
if checkRay == true then
local dist = (character.HumanoidRootPart.Position - targetRoot.Position).Magnitude
if distance < nearestDistance then
currentTarget = v
nearestDistance = distance
end
if currentTarget ~= nil then
local savedTarget = currentTarget
local targetRoot = currentTarget.PrimaryPart
local human = currentTarget:FindFirstChildWhichIsA("Humanoid")
if distance > range then
currentTarget = nil
end
end
end
else
currentTarget = nil
end
end
end
local currentTarget = nil
local function castRay(target)
if target.PrimaryPart ~= nil then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npcs}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.IgnoreWater = true
local rayOrigin = character.PrimaryPart.Position
local rayDestination = target.PrimaryPart.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
currentTarget = target
return true, raycastResult.Position, distance
end
end
end
currentTarget = nil
return false, nil, nil
end
local function findTarget()
local checkRay, position, distance = nil, nil, nil
local nearestDistance = math.huge
for i,v in ipairs(npcs:GetChildren()) do
local targetRoot = v.PrimaryPart
local human = v:FindFirstChildWhichIsA("Humanoid")
if targetRoot ~= nil and human and human.Health > 0 then
checkRay, position, distance = castRay(currentTarget or v)
if checkRay == true then
local dist = (character.HumanoidRootPart.Position - targetRoot.Position).Magnitude
if distance < nearestDistance then
currentTarget = v
nearestDistance = distance
end
if currentTarget ~= nil then
local savedTarget = currentTarget
local targetRoot = currentTarget.PrimaryPart
local human = currentTarget:FindFirstChildWhichIsA("Humanoid")
if distance > range then
currentTarget = nil
end
if player and distance <= attackRange then
else
humanoid.WalkSpeed = WalkSpeed
end
end
end
else
currentTarget = nil
end
end
end
local closestTarget = nil
for i, v in pairs(targets) do
if closestTarget == nil then
closestTarget = v
end
local d = v.Position - (origin.Position).Magnitude
local closestD = (closestTarget.Position - origin).Magnitude
if d < closestD then
closestTarget = v
end
end
I wrote this without studio. Probably the worst way to achieve this, but here you go.