How would I go about checking for nearby Humanoids? I’m creating a ‘chain lightning’ ability, and I want it to chain towards the nearest humanoid within a certain range from the start of the lightning. The potential targets range from actual players, to NPCs located in workspace. I’ve thought about the following methods:
Region3. This is iffy because of the part limit, and I want parts in a certain radius, not a cube area.
Explosion.Hit. I’ve used this event in the past and it works well, but it’s hard to determine when the explosion finishes (AncestryChanged fires ~3 seconds after explosion is created). Without knowing that, it’s hard to determine when the Explosion.Hit property stopped firing (aka all parts fired). Plus, with a BlastRadius of 30+ studs I imagine it’s not too efficient.
Raycasting. Sending out a ton of rays in all directions probably wouldn’t work too well at far distances (~30 to 40 studs).
Raycasting 2. The only other way I can think of would be recursively searching workspace for all humanoids and then sending rays to them to check for obstacles. But I imagine a game with a TON of objects in workspace would make this inefficient. Maybe if I didn’t search recursively, and only the first level of models in workspace? I’d have to make sure not to include any NPCs in other models, but it could work?
for i, v in pairs(game.Players:GetPlayers()) do
if (v.Character.HumanoidRootPart.Position - LightningOriginPosition).magnitude <= (max distance) then
print(v.Name.." can be struck by lightning!")
end
end
This code will loop through the players, and if they’re within range of the origin of the lightning then it’ll print “Username can be struck by lightning!”)
If you put all of your NPC and character models into a single model, you can avoid searching the entire workspace for humanoids and just search the single model that contains significantly less parts than the entire workspace.
@Noxielotl That only finds players though. OP wants NPCs as well.
Roblox endorsed models in the Toolbox actually have a module that’s useful for checking for all existing Humanoids in the Workspace. It’s not useful if you’re using Humanoids for other purposes (i.e. displaying clothing items), though.
ROBLOX_HumanoidList.mod.lua
local humanoidList = {}
local storage = {}
function humanoidList:GetCurrent()
return storage
end
local function findHumanoids(object, list)
if object then
if object:IsA("Humanoid") then
table.insert(list, object)
end
for _, child in pairs(object:GetChildren()) do
local childList = findHumanoids(child, list)
end
end
end
local updateThread = coroutine.create(function()
while true do
storage = {}
findHumanoids(workspace, storage) -- I edited this part from game.Workspace
wait(3)
end
end)
coroutine.resume(updateThread)
return humanoidList
Alternatively, you can use CollectionService to tag Humanoids. You will most likely have to combine this with Instance::DescendantAdded, check if the descendant’s class is Humanoid, tag it then operate your code based on that tag and CollectionService’s methods. Check @raiinbowjake’s response for the page to CollectionService.