Improving my code when a player clicks on another player

Currently, I’ve been experimenting with creating a custom system similar to Natural Disaster Survival’s system where when a player clicks on another player, it shows a GUI that has buttons for the player to interact with.

The script works, however, I’m not really satisfied with the code because:

  • Clicking on one of a player’s body parts means that the script has to loop through all of the possible body parts for R6/R15 in an array to detect what body part the player clicks on.
  • Accessories that a player is wearing would interfere with the script even though the player clicked on a body part.

How should I improve this so that it’ll work more efficiently?

-- Client script in StarterPlayer/StarterPlayerScripts
-- Views information about the player that has been clicked

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

local BodyParts = { -- R6/R15 rig bodyparts
	"LeftFoot",
	"LeftHand",
	"LeftLowerArm",
	"LeftLowerLeg",
	"LeftUpperLeg",
	"LowerTorso",
	"RightFoot",
	"RightHand",
	"RightLowerArm",
	"RightLowerLeg",
	"RightUpperArm",
	"RightUpperLeg",
	"UpperTorso",
	"Head",
	"HumanoidRootPart",
	"Left Arm",
	"Right Arm",
	"Right Leg",
	"Torso"
}

-- Checks if Mouse.Target is a BodyPart
local function CheckTarget(Target)
	if Target == nil then
		return 
	end
	
	for _, BodyPart in pairs(BodyParts) do
		if Target.Name == BodyPart then
			return Target.Parent
		end
	end
end

-- Fires whenever someone presses left mouse button
local function OnLeftClick()
	local Target = Mouse.Target
	local Clicked = CheckTarget(Target)
		
	if Clicked == nil then 
		return -- if target is nil, do nothing
	end
	
	local ClickedPlayer = Players:GetPlayerFromCharacter(Clicked)
	
	if ClickedPlayer == nil then -- BodyPart isn't part of an actual player
		return 
	end
	
	print(ClickedPlayer)
end

Mouse.Button1Down:Connect(OnLeftClick) -- Connect OnLeftClick() to an event

Instead of looping through a table of body parts try using Players:GetPlayerFromCharacter Function

3 Likes

Instead of using a table with the body parts maybe check if the target name or text is a child of the character by using :GetDescendants()

3 Likes

While I do appreciate both of the answers for my first problem (and I already implemented them) but I’m also looking for on how to get rid of interference from accessories when I click on a player (which is my second problem)

To check if it’s a body part:

if Target.Parent:FindFirstChild("Humanoid")  then
    print "It's a body part!"
end

To specifically check if it’s a hat:

if Target.Parent:IsA("Accoutrement") then
    print "It's a hat!"
end
3 Likes

Why not just try :IsDescendantOf()?
Then just loop over all the players’ characters.