Is There A Better Way To Get A Player Character From Only A Basepart

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

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
1 Like

If you really cared about performance then you would also alias the Parent instance to avoid redundant hierarchy path evaluation :stuck_out_tongue:

local charFolder = workspace.Characters

--tight loop
local parent = hitPart.Parent
if parent.Parent == charFolder then
    local char = parent

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} = {}

	for _, bp in ch:GetChildren() do
		if bp.CanQuery then
			hash[bp] = ch

local function garbageCollectHash()
	for bp, ch in hash do
		if not bp:IsDescendantOf(workspace) then
			hash[bp] = nil
		if not ch:IsDescendantOf(workspace) then
			hash[bp] = nil

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()

That’s also a possibility. The OP was asking for alternatives so may as well deliver all of them lol