Hello there. So, I created a little demo that does something similar to what you want. Here’s the code for that:
-- Services --
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Variables --
local Player = Players.LocalPlayer
local Character = Player.Character or Player.Character:Wait()
local HumanoidRootPart = Character.HumanoidRootPart
local Humanoids = workspace.Humanoids
local RadMax = workspace.RadMax
local RadMin = workspace.RadMin
local Highlight = ReplicatedStorage.Highlight
local MaxRadius = 30
-- Functions --
local function FindNearest()
local Closest -- Setting to nil since there is no reason to be set to anything.
local ClosestDistance = math.huge -- Setting it to math.huge in order to compare it.
for _, TargetCharacter in ipairs(Humanoids:GetChildren()) do -- Looping through all children of the "Humanoids" folder. In your case, this could be different, along with all the checks.
local TargetHumanoid = TargetCharacter:FindFirstChild("Humanoid") -- Gets the Humanoid of the model.
local TargetHumanoidRootPart = TargetCharacter:FindFirstChild("HumanoidRootPart") -- Gets the HumanoidRootPart of the model.
if TargetCharacter:IsA("Model") and TargetHumanoid and TargetHumanoidRootPart and TargetHumanoid.Health > 0 then -- Checking if the "TargetCharacter" is a model, has a Humanoid, has a HumanoidRootPart, and if the humanoid's healt his bigger than 0. This check could be specialized for your case.
local Distance = (HumanoidRootPart.Position - TargetHumanoidRootPart.Position).magnitude -- Gets the distance between the character's HumanoidRootPart and the target's HumanoidRootPart.
if Distance <= MaxRadius and Distance < ClosestDistance then -- Checking if the character is within our max radius and if the distance is smaller than the closest distance so far.
Closest = TargetCharacter -- Setting the closest character to the current one.
ClosestDistance = Distance -- Setting the closest character distance to the current one.
end
end
end
if not Closest then ClosestDistance = nil end -- Set the ClosestDistance to nil if there is no close player.
return Closest, ClosestDistance -- Return Closest and ClosestDistance.
end
-- Scripting --
RadMax.Size = Vector3.new(0.2, MaxRadius * 2, MaxRadius * 2)
while task.wait(0.1) do
RadMax.Position = Vector3.new(HumanoidRootPart.Position.X, 0.1, HumanoidRootPart.Position.Z)
local Closest, ClosestDistance = FindNearest()
if Closest then
Highlight.Parent = Closest
RadMin.Position = Vector3.new(HumanoidRootPart.Position.X, 0.15, HumanoidRootPart.Position.Z)
RadMin.Size = Vector3.new(0.3, ClosestDistance * 2, ClosestDistance * 2)
RadMin.Parent = workspace
RadMax.Color = Color3.fromRGB(170, 170, 0)
else
Highlight.Parent = ReplicatedStorage
RadMin.Parent = ReplicatedStorage
RadMax.Color = Color3.fromRGB(31, 128, 29)
end
end
And here’s a little clip of how it works:
As you can see, it will always “lock” onto the closest character that meets the requirement, which are that it is a character, that its health is greater than zero, and that it is a 30-stud radius of the player.
Now, this is meant to be used as a concept. I put comments on each line of the FindNearest()
function that explain what is happening. You should modify it to work for your case, but nonetheless, that is how it’s going to work;
- Check if it is a character and has both a Humanoid and HumanoidRootPart
- Check if its health is greater than 0
- Check if it is within your max radius
- Check if the distance is smaller than the currently smallest distance
4.1 If it is, set it to be the closest and the smallest distance
- Return the closest and smallest distance, if any
Hopefully this helped you. If you have any questions, do let me know.