How to check who killed people using ROBLOX's Endorsed Weapons?

  1. What do you want to achieve?
    I want to know who killed a person using ROBLOX’s Weapons to create a wanted level system for my upcoming game.
3 Likes

With the ROBLOX Original Sword, they implemented a system were when you hit a player, it tags them aka Combat Logging. You can use that to determine which player killed that player.

Here’s an example (Script located in StarterCharacter):

local char = script.Parent
local humanoid = char:WaitForChild("Humanoid")

humanoid.Died:Connect(function()
    if (humanoid:FindFirstChild("TagName")) then --Not the exact name of the tag
        local player = humanoid.TagName.Value
        --give player reward
    end
end)

I’m not sure if this is in the new ROBLOX weapons like the new guns but this is an example for the Sword.
You can find the tag / tag name by either digging up the main script or looking in an npc’s humanoid for the tag.

2 Likes

I think the sword has an object value which you could use, other than that you’d have to implement it yourself.

It is for ROBLOX’s endorsed guns like the pistol

An easy way to do this is to add a tag to the player when a weapon hits them and then to read the tag when they die and award points. Obviously if a player is hit by multiple other players the last tag found will be applied.

To do this, in ServerScriptService add a script with the following:

local Players = game:GetService("Players")
Players.PlayerAdded:connect(function(player)
-- SETUP PLAYER STATS
	local folder = Instance.new("Folder", player)
	folder.Name = "leaderstats"
	local PlayerKills = Instance.new("IntValue", folder)
	PlayerKills.Name = "Kills"
-- ADD KILL :Connect function
	player.CharacterAdded:connect(function(Character) -- When they respawn (Get a new Character)
		local Humanoid = Character:WaitForChild("Humanoid") -- Find Humanoid
		Humanoid.Died:connect(function() -- Detects for when the Humanoid dies
			if Humanoid:FindFirstChild("creator") ~= nil then -- Checks for a Killed
				local player = Humanoid.creator.Value
				print(player, " killed", Humanoid)
-- Update Leaderstats				
				player.leaderstats.Kills.Value = player.leaderstats.Kills.Value + 1
			end
			-- For the Dead guy, you can do stuff to him here.
		end)
	end)
end)

Then you need to update the modulescript in ReplicatedStorage > WeaponsSystem > WeaponsSystem to add the required tags when the player gets hit.
First add a couple of new functions in this script:

--       ADD CREATOR TAGS FOR WEAPON HITS      --
--            NEEDED FOR LEADERSTATS             --

function TagHumanoid(humanoid, player)
--	print("Rscript: ", player, " tagged ", humanoid)
	local Creator_Tag = Instance.new("ObjectValue")
	Creator_Tag.Name = "creator"
	Creator_Tag.Value = player
	Creator_Tag.Parent = humanoid
end

function UntagHumanoid(humanoid)
	for i, v in pairs(humanoid:GetChildren()) do
		if v:IsA("ObjectValue") and v.Name == "creator" then
			v:Destroy()
		end
	end
end

Then in the same modulescript find the WeaponsSystem.doDamage function and before the final 2 end statements in that function add:

		UntagHumanoid(target)
		TagHumanoid(target, dealer)

This will remove any previous tags from player hits so that the last shot awards the points.

The endorsed Roblox Weapons Kit is a great resource which my son has used extensively in his game [Insert Game Name Here] - Roblox and I have modified a little.

Let us know how you get on.

4 Likes

Can it work when theres an already existing leaderstats?

where you do the damage dealing do this

for ex:

if humanoid.Health - damage <= 0 then
  print(attacker.Name, 'Killed', target.Name)
end

if it doesn’t work try adding tonumber(humanoid.Health - damage)

where do you put this line of script?

read the thing that i said again

Is this correct?

	if not target or CollectionService:HasTag(target, "WeaponsSystemIgnore") then
		return
	end
	--if IsServer then
		if target:IsA("Humanoid") and dealer:IsA("Player") and dealer.Character then
			local dealerHumanoid = dealer.Character:FindFirstChildOfClass("Humanoid")
			local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
			if dealerHumanoid and target ~= dealerHumanoid and targetPlayer then
				-- Trigger the damage indicator
			WeaponData:FireClient(targetPlayer, "HitByOtherPlayer", dealer.Character.HumanoidRootPart.CFrame.Position)
			UntagHumanoid(target)
			TagHumanoid(target, dealer)
			if humanoid.Health - damage <= 0 then
				print(attacker.Name, 'Killed', target.Name)
			end
		end
		end

		-- NOTE:  damageData is a more or less free-form parameter that can be used for passing information from the code that is dealing damage about the cause.
		-- .The most obvious usage is extracting icons from the various weapon types (in which case a weapon instance would likely be passed in)
		-- ..The default weapons pass in that data
		local handler = _damageCallback or _defaultDamageCallback
		handler(WeaponsSystem, target, amount, damageType, dealer, hitInfo, damageData)
	--end
end

Use the soloution as help Detect Kill and Reward is not working

Your existing leaderstats will be created on a PlayerAdded:Connect event. Just add the KILL : Connect function inside that event handler and change the leaderstats objects to use yours.

Is this correct?

game.Players.PlayerAdded:connect(function(player)
	local folder = Instance.new("Folder", player)
	folder.Name = "leaderstats"
	
	local Cash = Instance.new("IntValue", folder)
	Cash.Name = "Cash"
	
	local Hunger = Instance.new("IntValue", folder)
	Hunger.Name = "Hunger"
	Hunger.Value = 100
	
	local Thirst = Instance.new("IntValue", folder)
	Thirst.Name = "Thirst"
	Thirst.Value = 100

	local PlayerKills = Instance.new("IntValue", folder)
	PlayerKills.Name = "Kills"
		-- ADD KILL :Connect function
		player.CharacterAdded:connect(function(Character) -- When they respawn (Get a new Character)
			local Humanoid = Character:WaitForChild("Humanoid") -- Find Humanoid
			Humanoid.Died:connect(function() -- Detects for when the Humanoid dies
				if Humanoid:FindFirstChild("creator") ~= nil then -- Checks for a Killed
					local player = Humanoid.creator.Value
					print(player, " killed", Humanoid)
					-- Update Leaderstats				
					player.leaderstats.Kills.Value = player.leaderstats.Kills.Value + 1
				end
				-- For the Dead guy, you can do stuff to him here.
			end)
	end)
end)

Yup. So now you can track Kills.

SO, how are you going to approach the next part “wanted level system for my upcoming game”?

Before I answer that question, may I ask do I put the “function TagHumanoid” on the very top? and may I know regarding the WeaponsSystem.doDamage function to see if this is correct?

	if not target or CollectionService:HasTag(target, "WeaponsSystemIgnore") then
		return
	end
	--if IsServer then
		if target:IsA("Humanoid") and dealer:IsA("Player") and dealer.Character then
			local dealerHumanoid = dealer.Character:FindFirstChildOfClass("Humanoid")
			local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
			if dealerHumanoid and target ~= dealerHumanoid and targetPlayer then
				-- Trigger the damage indicator
			WeaponData:FireClient(targetPlayer, "HitByOtherPlayer", dealer.Character.HumanoidRootPart.CFrame.Position)
		end
		UntagHumanoid(target)
		TagHumanoid(target, dealer)
		end

		-- NOTE:  damageData is a more or less free-form parameter that can be used for passing information from the code that is dealing damage about the cause.
		-- .The most obvious usage is extracting icons from the various weapon types (in which case a weapon instance would likely be passed in)
		-- ..The default weapons pass in that data
		local handler = _damageCallback or _defaultDamageCallback
		handler(WeaponsSystem, target, amount, damageType, dealer, hitInfo, damageData)
	--end
end```

I added the new TagHumanoid & UntagHumanoid functions after the variables are defined as I wasn’t sure where else I might be using it:

local _damageCallback = nil
local _getTeamCallback = nil
-- functions added below here...

My full equivalent WeaponsSystem.doDamage function is this currently:

function WeaponsSystem.doDamage(target, amount, damageType, dealer, hitInfo, damageData)
	if not target or ancestorHasTag(target, "WeaponsSystemIgnore") then
		return
	end
	if IsServer then
		if target:IsA("Humanoid") and dealer:IsA("Player") and dealer.Character then
			local dealerHumanoid = dealer.Character:FindFirstChildOfClass("Humanoid")
			local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
			if dealerHumanoid and target ~= dealerHumanoid and targetPlayer then
				-- Trigger the damage indicator
				WeaponData:FireClient(targetPlayer, "HitByOtherPlayer", dealer.Character.HumanoidRootPart.CFrame.Position)
			end
		end

		-- NOTE:  damageData is a more or less free-form parameter that can be used for passing information from the code that is dealing damage about the cause.
		-- .The most obvious usage is extracting icons from the various weapon types (in which case a weapon instance would likely be passed in)
		-- ..The default weapons pass in that data
		local handler = _damageCallback or _defaultDamageCallback
		handler(WeaponsSystem, target, amount, damageType, dealer, hitInfo, damageData)
		UntagHumanoid(target)
		TagHumanoid(target, dealer)
	end
end
1 Like

Also from what I have noticed in the script, there is another function with a similar name to the “TagHumanoid” you provided, does that have to do with anything? Or do I remove it

There is the getHumanoid function which checks to see what the weapon has hit and whether it has an associated HumanoidRootPart, which detects if you have hit a player or an NPC

Okay, sorry for the really late reply but I have one final question, how do I get the Humanoid’s player when they died, I’m thinking so that if a player kills that person with a bounty, they get their bounty.

I have a standard function I run to get Player from the Humanoid:

local function getPlayerFromName(name)
-- loop over all players:
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
-- if their name matches (case insensitive), return with that player:
		if player.Name:lower() == name:lower() then
			return player
		end
	end
	-- if we reach the end of the for-loop, no player with that name was found
end

-- if you have the Humanoid then you can call the function above using:
local player = getPlayerFromName(Humanoid.Parent.Name)


Alternatively, if you have the Character then we can use the following, which is a Roblox built-in API call:

local player = game.Players:GetPlayerFromCharacter(character)

I hope this helps. Which one you decide to use will be determined by how much information you have at the point at which you call it.