Hi, I wrote a question about the use of my RemoteEvents because of the error I was having. I now have no errors, but the script still does not deal damage to the player that is being attacked. The tool has one local script, a RemoteEvent in a folder in ReplicatedStorage, and a script in ServerScriptService to activate when the RemoteEvent is fired.
The local script is this:
local player = game.Players.LocalPlayer local char = player.Character local hum = char:WaitForChild("Humanoid") repeat wait() until char repeat wait() until hum local attackanim = script:WaitForChild("SlashAnim2") attackanim.Parent = char local animtrack = hum:LoadAnimation(attackanim) local tool = script.Parent local damage = 30 local debounce = false local attacking = false local attackingtouch = false local rs = game:GetService("RunService") local debris = game:GetService("Debris") function onEquip() enabled = true animtrack:Stop() end function onActivate() if debounce == false then debounce = true attacking = true attackingtouch = true animtrack:Play() wait(1) attackingtouch = false debounce = false attacking = false end end function onTouch(part) if attackingtouch == true and debounce == true then if part.Parent.Name ~= player.Name then local vhum = part.Parent:findFirstChild("Humanoid") if vhum and vhum.Health > 0 then game.ReplicatedStorage.RemoteEvents.TakeHealthFromWeapon:FireServer(vhum, damage) attackingtouch = false end end end end function onUnequip() enabled = false animtrack:Stop() end tool.Equipped:connect(onEquip) tool.Activated:connect(onActivate) tool.Handle.Touched:connect(onTouch) tool.Unequipped:connect(onUnequip)
The script in ServerScriptService looks like this:
function onTHFW(Player, vhum, damage) vhum.Health = vhum.Health - damage end game.ReplicatedStorage.RemoteEvents.TakeHealthFromWeapon.OnServerEvent:connect(onTHFW)
As I said before, I get no errors. What am I doing wrong? Thanks. :} ~Loughdough
Ok; here I go:
The first thing you need to understand is that tools like swords, and guns are not very functional in a filtering enabled environment, unless they are replicated over both the server, and the cleint(s). To achieve this, you should usually store tools inside ReplicatedStorage
, and clone the tool in replicated storage into a certain player's backpack down the road instead, however do not store your remote event inside of the tool; instead make sure your remote event is stored directly in ReplicatedStorage (i.e. so you could say game.ReplicatedStorage.my_remote_event
)
From this point on, I will refer to your sword tool as 'Tool', and a standard remote event as 'r'
Typically to start a game, you would want to get the recent player that joined, and you typically do that with game.Players.PlayerAdded, however with filtering enabled, getting the player that joined is a bit different.
Insert a local script into
game.StarterPlayer.StarterPlayerScripts
; It's code should be something along the lines of:
local r = game.ReplicatedStorage.remote_event; r:FireServer("Join");
this script is the script that fires to the server whenever its client joins the game. (this works because all local scripts are replicated to each client when they join a server)
Insert a server script (a script) into
game.ServerScriptService
that can manage cloning and giving out the Tool to every player when they join, or are re-spawned; its code should be something along the lines of:
local r = game.ReplicatedStorage.remote_event; local my_tool = game.ReplicatedStorage.Tool; r.OnServerEvent:connect(function(plr, info) if info == "Join" then --just to be on the safe side i am adding a waitforchild incase the player's backpack does not exist yet, since they just joined the server. plr:WaitForChild("Backpack"); my_tool:Clone().Parent = plr.Backpack; end --when the player's character is changed is essentially when the player is respawned, because ROBLOX has to create a new character for the player. plr.Changed:connect(function(prop) if prop == "Character" then my_tool:Clone().Parent = plr.Backpack; end end) end)
I will be referring to this script as 'main' from this point on.
So now that the basics of Filtering enabled are all out of the way, lets get down to analyzing the code inside of the local script of your Tool; change its code to:
local player = game.Players.LocalPlayer local r = game.ReplicatedStorage.remote_event; local attackanim = script:WaitForChild("SlashAnim2") local tool = script.Parent local damage = 30 local current_track; local debounce = false; local attacking = false local attack_debounce = false; --by the time a player activates a tool, their character, and humanoid will already be loaded in. tool.Activated:connect(function() if not debounce then debounce = true; local hmd = player.Character:FindFirstChild("Humanoid"); current_track = hmd:LoadAnimation(attackanim); attacking = true; current_track:Play(); local event; event = current_track.Stopped:connect(function() attacking = false; wait(0.2); debounce = false; event:disconnect(); end); end end) tool.Handle.Touched:connect(function(part) if not attack_debounce then attack_debounce = true; if attacking then local plr_hmd = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid"); --always take into account whether the tool hit an accessorie's Handle on the other player as well (i.e. part.Parent.Parent) if plr_hmd ~= nil then local plr_name = plr_hmd.Parent.Name; if player.Name ~= plr_name then r:FireServer("Hit", plr_hmd.Parent, damage); end end end attack_debounce = false; end end) tool.Unequipped:connect(function() if current_track ~= nil then current_track:Stop(); current_track:Destroy(); current_track = nil; end attack_debounce = false; attacking = false; debounce = false; end)
We are using the same remote event for Tool, as we did for our join script. So now we can go back and edit main's code to something more like this so that it can also handle whenever a player attacks another player:
local r = game.ReplicatedStorage.remote_event; local my_tool = game.ReplicatedStorage.Tool; r.OnServerEvent:connect(function(plr, ...) local inf_table = {...}; if inf_table[1] == "Join" then --just to be on the safe side i am adding a waitforchild incase the player's backpack does not exist yet, since they just joined the server. plr:WaitForChild("Backpack"); my_tool:Clone().Parent = plr.Backpack; elseif inf_table[1] == "Hit" then if game.Players:GetPlayerFromCharacter(inf_table[2]) then inf_table[2].Humanoid:TakeDamage(inf_table[3]); end end --when the player's character is changed is essentially when the player is respawned, because ROBLOX has to create a new character for the player. plr.Changed:connect(function(prop) if prop == "Character" then my_tool:Clone().Parent = plr.Backpack; end end) end)
I am too tired to explain any more, if you are still having problems with it, send me details and I will see what I can do to help.
I hope this helps you.