Hi, I have an issue. I’m making a combat engine, and I’ve gotten most thing working such as bullets, but there is one issue I came across just now and cant find solutions for.
Whenever the bullet hits an object, it cant detect if it is inside a character [not just players but NPCs too], making it so it can’t damage. I know why, which is because my playermodels are made up of quite a few parts, and they are fairly deep inside the characters model. Here’s how they look.
[REMOVED]
And back to the question, how would I loop through all the parents of an instance parents without any delay? [a repeat until loop worked great, but since I had to use a wait() it caused a noticeable delay in damaging the players.]
Yes i tried the following :
instance.Parent:FindFirstChild("Humanoid") or instance.Parent.Parent:FindFirstChild("Humanoid") --so on
but it errored mainly because it kept trying to get the parent of Game, and its also not the best way to do it.
Quick Example incase you still don’t get what I’m trying to say :
You can also do a recursive function for this purpose. I’ve done it for a vehicle chassis debugging plugin to search for the main parent script.
local function searchUntilPlugin(currentAsset)
if currentAsset.Parent.Name ~= "Plugins" and currentAsset.Parent ~= game.Workspace then
return searchUntilPlugin(currentAsset.Parent)
else
return currentAsset
end
end
Ok, so it works but now the issue is it keeps damaging the humanoid over and over, even just from one shot. And idea what causes this?
My implementation :
Probably you have some boolean that isnt registering the fact that it was hit once. Since the getHuman() method you adapted from my suggestions shouldn’t be causing trouble. Also touched events tend to fire multiple times if thats what your using.
KONNICHIWA!
Assuming your humanoids don’t have additional models in them then you can just use
:FindFirstAncestorOfClass()
function getHuman(instance)
local Character = instance:FindFirstAncestorOfClass("Model")
if Character and Character:FindFirstChild("Humanoid") then
return Character.Humanoid
end
end
Kon’nichiwa again!
In that case you can just use :FindFirstAncestor and make a whitelist for players and npc’s like this:
local NPC_Names = {"Idk", "What_your", "NPC's","Are called"}
function WhiteList()
local WhiteL = {}
local Players = game.Players:GetPlayers()
for i,Player in pairs(Players) do
table.insert(WhiteL,Player.Name)
end
for i,NPCName in pairs(NPC_Names) do
table.insert(WhiteL,NPCName)
end
return WhiteL
end
function getHuman(instance)
local WL = WhiteList()
local Character = nil
for i, CheckWL in pairs(WL) do
if instance:FindFirstAncestor(CheckWL) then
Character = instance:FindFirstAncestor(CheckWL)
break
end
end
if Character ~= nil and Character:FindFirstChild("Humanoid") then
return Character.Humanoid
end
end
This should also easily allow you to base the whitelist on other factors such as the players team with a bit of tweaking. It’s much better than the method I suggested before!
This should properly do exactly what you are asking about! Let me know what you think!
It would still work, just use whatever method you normally use to detect the bots.
Bots are in a organized folder?
local BotFolder = workspace.BotFolder
function WhiteList()
local WhiteL = {}
local Players = game.Players:GetPlayers()
for i,Player in pairs(Players) do
table.insert(WhiteL,Player.Name)
end
for i,Bot in pairs(BotFolder:GetChildren()) do
table.insert(WhiteL,Bot.Name)
end
return WhiteL
end
Bots are not in a folder?
If the bots are not organized into a folder, but are just spawned into workspace; then you can just check for whatever unique item they have, such as bool in the character that regular players don’t have.
function WhiteList()
local WhiteL = {}
local Players = game.Players:GetPlayers()
for i,Player in pairs(Players) do
table.insert(WhiteL,Player.Name)
end
for i,Bot in pairs(workspace:GetChildren()) do
if Bot:FindFirstChild("WhateverTheItemInTheBotsIsCalled") then
table.insert(WhiteL,Bot.Name)
end
end
return WhiteL
end
I was just thinking you would say that!
All bases covered?
Ah, never mind! This worked perfectly, it was just an issue with my raycast which has been fixed. It detected multiple hits on a part at once, but I fixed it and now the damage works great with any humanoid. Thanks a lot for the help you guys!
Removed pictures and videos for classification purposes
local starterChar = script:FindFirstAncestor("StarterCharacter")
local starterChatDescendants = starterChar:GetDescendants()
for i, v in pairs(starterChatDescendants) do
--do stuff with the descendants of starter char
end
Place the script inside the part itself, this is likely the simplest way to achieve this task.