Method for detecting if a part is apart of a character of not

Hi everyone.

I am working on a game where you can pick up objects and also players/NPCs, and I want to handle players differently to the objects (like scream sound effects or ragdoll), how would i make a method for detecting if a part is apart of a character of not, like Part:IsApartOfCharacter() -> True/False or something?.

I have “GrabObject” which is Player:GetMouse().Target and is set when the user clicks on any unanchored part.

Here is the entire 358 lines of the script (not done yet, but gets the job done).

local CAS = game:GetService("ContextActionService")
local Players = game:GetService("Players")

local GrabObject = nil
local GrabStart = false
local Dragger = nil

Dist = 6

local MaxDist = 20
local minDist = -20

local DBuffer = nil
local ADir = {}

local player = game.Players.LocalPlayer
local character = player.Character
local mouse = player:GetMouse()
local camera = game.Workspace.CurrentCamera

local ServerPlayers = {}

local CPart = Instance.new("Part") --For corner visuals

--CPart.Shape = Enum.PartType.Ball
CPart.Size = Vector3.new(.3,.3,.3)
CPart.Transparency = .8
CPart.Color = Color3.new(0.3, 1, 0.35)
CPart.CanCollide = false
CPart.Material = Enum.Material.SmoothPlastic

-------------------------------------------------{ Rotation }-------------------------------------------------

function Rotate(actionName, UserInputState, InputObject)
	print("Start")
	local amount = Vector3.new(2,2,2)
	local RotSpeedReduce = 4
	if actionName == "Grab" then
		if UserInputState == Enum.UserInputState.Begin then
			CAS:BindAction("RotateX", Rotate, false, Enum.KeyCode.E)
			CAS:BindAction("RotateY", Rotate, false, Enum.KeyCode.R)
			CAS:BindAction("RotateZ", Rotate, false, Enum.KeyCode.T)
		elseif UserInputState == Enum.UserInputState.End then
			CAS:UnbindAction("RotateX")
			CAS:UnbindAction("RotateY")
			CAS:UnbindAction("RotateZ")
		end
	elseif actionName == "RotateX" then
		while actionName == "RotateX" do
			print("Rot")
			GrabObject.CFrame = CFrame.Angles(-amount.X * RotSpeedReduce,0,0) * GrabObject.CFrame
			wait(.05)
		end
	elseif actionName == "RotateY" then
		while actionName == "RotateY" do
			print("Rot")
			GrabObject.CFrame = CFrame.Angles(0, -amount.y * RotSpeedReduce,0) * GrabObject.CFrame
			wait(.05)
		end
	elseif actionName == "RotateZ" then
		while actionName == "RotateZ" do
			print("Rot")
			GrabObject.CFrame = CFrame.Angles(0,0, -amount.z * RotSpeedReduce) * GrabObject.CFrame
			wait(.05)
		end
	end
end

-------------------------------------------------{ Throwing }-------------------------------------------------

function Throw(actionName, UserInputState, InputObject)
	if actionName == "Throw" then
		if UserInputState == Enum.UserInputState.Begin then
			if GrabObject then
				if GrabObject.Anchored == false then
					wait()
					if Dragger then
						Dist = 6
						CAS:UnbindAction("Rotate")
						Dragger:Destroy()
						Dragger = nil
						if character.HumanoidRootPart.AttachmentObject then
							character.HumanoidRootPart.AttachmentObject:Destroy()
						end

						local newRot = Instance.new("BodyGyro", GrabObject)
						newRot.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
						newRot.P = 5000
						newRot.D = 800
						newRot.CFrame = game.Workspace.CurrentCamera.CFrame
						newRot.Name = "RotMover"

						local BV = Instance.new("BodyVelocity", GrabObject);
						BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
						BV.Velocity = game.Workspace.CurrentCamera.CFrame.lookVector * 50 -- how fast it throws
						wait(.2)
						GrabObject.BodyVelocity:Destroy()
						GrabObject.RotMover:Destroy()
						game.ReplicatedStorage.SetNetworkOwnership:FireServer(GrabObject, "Server") -- Reset network ownership
						GrabObject = nil
						GrabStart = false
						CAS:UnbindAction("Throw")
					end
				end
			end
		end
	end
end

-------------------------------------------------{ Grabbing }-------------------------------------------------

function Grab(actionName, UserInputState, InputObject)
	if actionName == "Grab" then
		if UserInputState == Enum.UserInputState.Begin then
			if Dragger then
				Dist = 6
				if GrabObject.Anchored == false then
					game.ReplicatedStorage.SetNetworkOwnership:FireServer(GrabObject, "Server")
				end
				CAS:UnbindAction("Rotate")
				CAS:UnbindAction("Throw")
				GrabObject = nil
				GrabStart = false
				Dragger:Destroy()
				Dragger = nil
				if character.HumanoidRootPart.AttachmentObject then
					character.HumanoidRootPart.AttachmentObject:Destroy()
				end

			else
				local Magnitude = (mouse.Hit.Position - character.Head.CFrame.Position).magnitude

				if Magnitude <= 20 then
					wait()
					if mouse.Target then
						if Dragger then
							Dist = 6
							if GrabObject.Anchored == false then
								game.ReplicatedStorage.SetNetworkOwnership:FireServer(GrabObject, "Server")
							end
							CAS:UnbindAction("Rotate")
							CAS:UnbindAction("Throw")
							GrabObject = nil
							GrabStart = false
							Dragger:Destroy()
							Dragger = nil
							if character.HumanoidRootPart.AttachmentObject then
								character.HumanoidRootPart.AttachmentObject:Destroy()
							end
						end

						GrabObject = mouse.Target
						
						-- where the character detection is needed
						
						GrabStart = true

						if GrabObject.Anchored == false then
							game.ReplicatedStorage.SetNetworkOwnership:FireServer(GrabObject, "Player")
						end

						CAS:BindAction("Rotate", Rotate, false, Enum.KeyCode.LeftShift)
						--CAS:BindAction("Place", Place, false, Enum.KeyCode.F)

						local DragBall = createDragBall()
						DragBall.CFrame = mouse.Hit
						DragBall.Sound.Playing = true
						Dragger = DragBall

						mouse.TargetFilter = GrabObject

						print(GrabObject.Name .. " Was grabbed")

						local DragBallWeld = weldBetween(DragBall,GrabObject)
						addMover(DragBall)

						local Attachment1 = Instance.new("Attachment")
						local Attachment0 = Instance.new("Attachment")
						local Beam = script.Beam
						Attachment1.Name = "AttachmentObject"
						Beam.Attachment1 = Attachment1
						Beam.Attachment0 = Attachment0
						Attachment0.Parent = Dragger
						Attachment1.Parent = character.HumanoidRootPart

						Object(GrabObject, Dragger)

						CAS:BindAction("Throw", Throw, true, Enum.UserInputType.MouseButton2)
						
						if GrabObject.Name == "Duckie" then
							script["Quack Sound"].Playing = true
						end

						while Dragger do
							--Create a ray from the users head to the mouse.
							local cf = CFrame.new(character.Head.Position, mouse.Hit.Position)
							Dragger.Mover.Position = (cf + (cf.LookVector * Dist)).Position
							Dragger.RotMover.CFrame = camera.CFrame * CFrame.Angles(Dragger.RotOffset.Value.X,--[[Dragger.RotOffset.Value.Y]] 0, Dragger.RotOffset.Value.Z)
							--Dragger.RotMover.CFrame = CFrame.new(camera.CFrame.X,GrabObject.CFrame.Y,camera.CFrame.Z) * CFrame.Angles(Dragger.RotOffset.Value.X, Dragger.RotOffset.Value.Y, Dragger.RotOffset.Value.Z)
							wait()
						end
						mouse.TargetFilter = nil
					end
				end
			end
		end
	end
end

-------------------------------------------------{ Other }-------------------------------------------------

function weldBetween(a, b)
	local weld = Instance.new("ManualWeld", a)
	weld.C0 = a.CFrame:inverse() * b.CFrame
	weld.Part0 = a
	weld.Part1 = b
	return weld
end

function addMover(part)
	local newMover = Instance.new("BodyPosition")
	newMover.Parent = part
	newMover.MaxForce = Vector3.new(60000,60000,60000)
	newMover.P = 60000
	newMover.D = 2000
	newMover.Position = part.Position
	newMover.Name = "Mover"

	local newRot = Instance.new("BodyGyro")
	newRot.Parent = part
	newRot.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
	newRot.P = 5000
	newRot.D = 800
	newRot.CFrame = game.Workspace.CurrentCamera.CFrame
	newRot.Name = "RotMover"

	local RotOffset = Instance.new("CFrameValue")
	RotOffset.Name = "RotOffset"
	RotOffset.Parent = part
end

function createDragBall()
	local DragBall = Instance.new("Part")
	local sound = script.Sound1:Clone()
	sound.Parent = DragBall
	sound.Name = "Sound"
	DragBall.BrickColor = BrickColor.new("Bright green")
	DragBall.Material = Enum.Material.SmoothPlastic
	DragBall.Size = Vector3.new(.3,.3,.3)
	DragBall.Shape = "Ball"
	DragBall.Name = "DragBall"
	DragBall.Parent = workspace
	return DragBall
end

function Object(Part, Par)
	local Size = Part.Size
	local ObjCorners = {
		Corner1 = Part.CFrame * CFrame.new(-Size.X/2, -Size.Y/2, -Size.Z/2),
		Corner2 = Part.CFrame * CFrame.new(Size.X/2, -Size.Y/2, Size.Z/2),
		Corner3 = Part.CFrame * CFrame.new(-Size.X/2, Size.Y/2, -Size.Z/2),
		Corner4 = Part.CFrame * CFrame.new(Size.X/2, Size.Y/2, Size.Z/2),

		Corner5 = Part.CFrame * CFrame.new(-Size.X/2, -Size.Y/2, Size.Z/2),
		Corner6 = Part.CFrame * CFrame.new(Size.X/2, -Size.Y/2, -Size.Z/2),
		Corner7 = Part.CFrame * CFrame.new(-Size.X/2, Size.Y/2, Size.Z/2),
		Corner8 = Part.CFrame * CFrame.new(Size.X/2, Size.Y/2, -Size.Z/2),
	}

	--local Border = Instance.new("SelectionBox")
	--Border.Parent = Part
	--Border.Transparency = .5
	--Border.Adornee = Part
	--Border.LineThickness = .1
	--Border.Color3 = Color3.new(0.5, 1, 0.3)
	--Border.Name = "Border"

	local Cpart1 = CPart:Clone()
	local Cpart2 = CPart:Clone()
	local Cpart3 = CPart:Clone()
	local Cpart4 = CPart:Clone()
	local Cpart5 = CPart:Clone()
	local Cpart6 = CPart:Clone()
	local Cpart7 = CPart:Clone()
	local Cpart8 = CPart:Clone()

	Cpart1.CFrame =  ObjCorners.Corner1
	Cpart2.CFrame =  ObjCorners.Corner2
	Cpart3.CFrame =  ObjCorners.Corner3
	Cpart4.CFrame =  ObjCorners.Corner4
	Cpart5.CFrame =  ObjCorners.Corner5		
	Cpart6.CFrame =  ObjCorners.Corner6
	Cpart7.CFrame =  ObjCorners.Corner7
	Cpart8.CFrame =  ObjCorners.Corner8

	Cpart1.Parent = Par
	Cpart2.Parent = Par
	Cpart3.Parent = Par
	Cpart4.Parent = Par
	Cpart5.Parent = Par
	Cpart6.Parent = Par
	Cpart7.Parent = Par
	Cpart8.Parent = Par

	weldBetween(Cpart1, Part)
	weldBetween(Cpart2, Part)
	weldBetween(Cpart3, Part)
	weldBetween(Cpart4, Part)
	weldBetween(Cpart5, Part)
	weldBetween(Cpart6, Part)
	weldBetween(Cpart7, Part)
	weldBetween(Cpart8, Part)

end

CAS:BindAction("Grab", Grab, true, Enum.UserInputType.MouseButton1)

--player.Backpack.Cones.Equipped:Connect(function()
--	if Dragger then
--		Dist = 6
--		GrabObject = nil
--		GrabStart = false
--		Dragger:Destroy()
--		Dragger = nil
--		if character.HumanoidRootPart.AttachmentObject then
--			character.HumanoidRootPart.AttachmentObject:Destroy()
--		end
--	end
--	CAS:UnbindAction("Grab", Grab, false, Enum.UserInputType.MouseButton1)
--end)

--player.Backpack.Cones.Unequipped:Connect(function()
--	CAS:BindAction("Grab", Grab, false, Enum.UserInputType.MouseButton1)
--end)

mouse.WheelBackward:Connect(function()
	if Dist > minDist then
		Dist = Dist - .4
	end
end)
mouse.WheelForward:Connect(function()
	if Dist < MaxDist then
		Dist = Dist + .4
	end
end)

character:WaitForChild("HumanoidRootPart").Touched:Connect(function(Part)
	if Part.Name == "DragBall" then
		character.Humanoid.Sit = true
	end
end)

character:WaitForChild("HumanoidRootPart").TouchEnded:Connect(function(Part)
	if Part.Name == "DragBall" then
		character.Humanoid.Sit = false
	end
end)

I have searched everywhere for this including api docs, google, and the forums and could not find what i was looking for.

Can’t you check if the part is parented under the character?

function GetChar(part)
  if part.Parent == workspace then
    if part:FindFirstChild("Humanoid") and part.Humanoid:IsA("Humanoid") then
      return part;
    end
  elseif part.Parent then
    return GetChar(part.Parent)
  end
end

This works for a character and npcs. Something like this might work for what you described.

To check if a part is a descendant of the character model, you can use the Instance method IsDescendantOf or the alternative IsAncestorOf.

If you want to determine whether a part is a limb of the character (e.g. LeftLeg, RightArm, etc.), you can use the character’s Humanoid method GetLimb. If the method returns an Enum value other than Unknown , then the part is a limb of the character.

Here is a simple function that checks whether a given part is a limb of the given character:

local function IsApartOfCharacter(Character: Model, Part: BasePart)
	if not Character:IsAncestorOf(Part) then return false end    -- Humanoid:GetLimb method will error if the given part is not a child of the character.
	if Character.PrimaryPart == Part then return true end
	local Humanoid = Character:FindFirstChildWhichIsA("Humanoid")
	
	if Humanoid and Humanoid:GetLimb(Part) ~= Enum.Limb.Unknown then
		return true
	end
	return false
end