I have a serverscript that allows players to knockback and ragdoll other players, but the issue I am currently facing is when the victim (the person being hit) resets, the script essentially freezes up. My solution to this problem was by having an attribute (victim:SetAttribute(“Opponent”, Player.Name)) store the name of the player who was currently hitting them so that I could reset that player’s cooldown upon Victim.CharacterRemoving. (I have a table that stores all of the player’s cooldowns).
local function characterRemoving(player)
print(player:GetAttribute("Opponent"))
for _, plr in pairs(players:GetPlayers()) do
if plr.Name == player:GetAttribute("Opponent") then
--resets player's cooldown
end
end
end
local function playerAdded(player)
player.CharacterAdded:Connect(function(character)
characterAdded(player, character)
end)
player.CharacterRemoving:Connect(characterRemoving)
if player.Character then
characterAdded(player, player.Character)
end
end
players.PlayerAdded:Connect(playerAdded)
However, upon testing this, and printing out the attribute “Opponent,” it simply returned void, despite the fact that it’s set to the string value “N/A” as soon as the player joins. When printing outside of the characterRemoving function, it prints out the player’s name as expected. Upon further testing, I’ve found that it returned void for any other attribute I printed. I am unsure if this is an issue due to my own scripting, or if it’s a bug. I’m also open to any alternate suggestions on how to solve my cooldown issue.
Extra information:
Players press a key to fire a remoteevent which activates the function to ragdoll other players. The script checks the player’s cooldown, as well as an attribute (player:GetAttribute(“Active”)) to determine whether or not a player is already attempting to hit their victim. When the function for ragdolling is activated, the script sets the player’s attribute “Active” to true and goes through a series of checks, however, if any of them fail to go through, “Active” is set back to false. When the victim resets, “Active” is never set back to false for the player.
I think it might be unrelated, but it sets the player’s cooldown.
local function characterAdded(player, character)
player.CharacterAppearanceLoaded:Wait()
task.wait(0.1)
if not tab[player] then
tab[player] = os.time()
print(player.Name.."'s cooldown was set.")
end
end
Yeah. I can also print out the attribute normally and it properly returns the player’s name anywhere else in the script, just not in player.CharacterRemoving for whatever reason.
The only argument CharacterRemoving passes when it fires is the character being removed, meaning that the player parameter is assigned to the character.
To clarify:
local function characterRemoving(player) --> player is assigned to the character being removed, not the player whose character is being removed.
print(player:GetAttribute("Opponent"))
for _, plr in pairs(players:GetPlayers()) do
if plr.Name == player:GetAttribute("Opponent") then
--resets player's cooldown
end
end
end
That will only run when the user joins the game, therefore I assume the player loads a bit after the attributes are set, causing them to be overridden. Instead try adding the attribute a bit later, just for testing reasons:
players.PlayerAdded:Connect(function(player)
task.wait(5) --just for testing
player:SetAttribute("Active", false)
player:SetAttribute("Opponent", "N/A")
end)
Keep in mind, the main idea is that the values should update when the opponent changes, I assume that they currently aren’t updating which will make the value constant and equal to "N/A".
local function playerAdded(player)
player.CharacterAdded:Connect(function(character)
characterAdded(player, character)
end)
player.CharacterRemoving:Connect(function()
characterRemoving(player)
end)
if player.Character then
characterAdded(player, player.Character)
end
end