Hello, I am making a combat system and I need to get the character from only a basePart without using hit.Parent or something like that. Are there better ways to get their character?
No. There aren’t. You could have a parent folder for all characters and then do
if hitPart:IsDescendantOf(characterFolder) then
-- Do stuff
end
but performance-wise, I would just do this:
if hitPart.Parent.Parent = workspace.Characters then -- assume workspace.Characters is created by
-- you and every Player Character is parented to it
local char = hitPart.Parent
end
1 Like
If you really cared about performance then you would also alias the Parent instance to avoid redundant hierarchy path evaluation
--init
local charFolder = workspace.Characters
--tight loop
local parent = hitPart.Parent
if parent.Parent == charFolder then
local char = parent
...
end
But to suggest a solution to the OP’s question, you could also hash every basepart belonging to a character into a hashmap and use that as a reference. But please be careful of memory leaks with this approach. Pseudocode below
local hash: {[BasePart]: Character} = {}
onCharacterAdded:Connect(function(ch)
for _, bp in ch:GetChildren() do
if bp.CanQuery then
hash[bp] = ch
end
end
end)
local function garbageCollectHash()
for bp, ch in hash do
if not bp:IsDescendantOf(workspace) then
hash[bp] = nil
continue
end
if not ch:IsDescendantOf(workspace) then
hash[bp] = nil
end
end
end
--hitreg
local character: Character? = hash[RaycastResult.Instance]
If we’re going down that route, wouldn’t it also be easy to check the network owner of the part (assuming the player is not taking network ownership of anything else)?
local function getPlayerFromPart(part)
return part:GetNetworkOwner()
end
That’s also a possibility. The OP was asking for alternatives so may as well deliver all of them lol