I’ve tried many ways,none of them worked,I have no other choice,just to get help from someone else.Here’s the script:
task.wait(1)
local tool = script.Parent
local sss = game:GetService("ServerScriptService")
local modules = sss:WaitForChild("Modules")
local attackmod = require(modules:WaitForChild("Attack"))
local abilityEvent = tool:FindFirstChild("Ability")
local sound = tool:FindFirstChild("Script"):WaitForChild("Sound")
local humanoid = tool.Parent:FindFirstChild("Humanoid")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UpdateHitsLeaderboard = ReplicatedStorage:WaitForChild("UpdateHitsLeaderboard")
local character
local player
local attackAnim
local attackData = {
Damage = 15,
StartUp = 0.2,
Knockback = Vector2.new(30,20),
Stun = 2,
Linger = 0.4,
Sound = "Bonk"
}
local cooldown = 1
local debounce = false
local abilityDebounce = false
local abilityCooldown = 7
local toolDebounce = false
local function onActivated(hit)
if toolDebounce then return end
toolDebounce = true
attackAnim:Play()
if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
print("YESSS,FINALLY")
attackmod.Start(character, tool, attackData)
local eChar = hit.Parent
local eHumanoid = eChar:FindFirstChild("Humanoid")
local eHumanoidRootPart = eChar:FindFirstChild("HumanoidRootPart")
local ePlr = game.Players:GetPlayerFromCharacter(eChar)
if eHumanoid and eHumanoidRootPart and ePlr then
local hits = player:FindFirstChild("leaderstats"):FindFirstChild("Hits")
if eChar ~= character and ePlr ~= player then
if eHumanoid.Health > 0 then
hits.Value = hits.Value + 1
end
end
else
print("haha noob")
end
else
print("ez")
end
task.wait(1)
toolDebounce = false
end
local function onAbility(newChar)
if newChar.Name == character.Name then
if abilityDebounce then return end
abilityDebounce = true
sound:Play()
wait(1.4)
for i=35,16,1 do
humanoid.WalkSpeed = i
wait(0.1)
end
abilityDebounce = false
wait(abilityCooldown)
end
end
local function onTouched(hit)
if debounce then return end
task.wait(1)
debounce = false
local model = hit:FindFirstAncestorOfClass("Model")
if model and model ~= character and not model:FindFirstChild("PlayerHit") then
if model.Values:FindFirstChild("BasicCounter") then
require(game:GetService("ReplicatedStorage"):WaitForChild("Modules"):WaitForChild("CounterMoves")).BasicCounter(character,model)
return
end
local humanoid = model:FindFirstChildWhichIsA("Humanoid")
if humanoid then
debounce = true
if game.Players:GetPlayerFromCharacter(model) then
local ePlr = game.Players:GetPlayerFromCharacter(model)
if ePlr.Equipped.Value == 9 then
return
end
end
end
end
end
tool.Equipped:Once(function()
character = tool.Parent
player = game.Players:GetPlayerFromCharacter(character)
attackAnim = character.Humanoid.Animator:LoadAnimation(script.Attack)
end)
tool.Activated:Connect(onActivated)
--tool.Hitbox.Touched:Connect(onTouched)
abilityEvent.OnServerEvent:Connect(onAbility)
What are you trying to do? Tool.Activated fires when the user clicks while the tool is equipped. It does not pass any arguments. Therefore hit will always be nil. So what are you trying to do?
Then you make a localscript inside of the tool and get the mouse position whenever the tool is activated. Then you raycast on the server and do whatever you want with the result:
--localscript in tool
local tool = script.Parent
local mouse = game.Players.LocalPlayer:GetMouse()
local remote = --remote in tool
tool.Activated:Connect(function()
remote:FireServer(mouse.Hit.Position)
--you can also pass mouse.Target
end)
And on the server you connect to the remote:
remote.OnServerEvent:Connect(function(plr, pos)
local rayparams = RaycastParams.new()
rayparams.FilterDescendantsInstances = {plr.Character}
rayparams.FilterType = Enum.RaycastFilterType.Exclude
local res = workspace:Raycast(handle.Position, (pos - handle.Position).Unit, params)
if not res or not res.Instance then return end
--do something with res.Instance or skip this and use mouse.Target
end)
Also who told you tool.activated passes the instance where the mouse was over when the user clicked??
When you have questions, you first try to find something about your question on the api documentation. If that fails you come here.
Even if you don’t know the api docs existed, built in studio intellisense will tell you that Tool.Activated accepts a callback that accepts no parameters and has a void return type.
ok, then you need to pass the part as a param of your function like
tool.Activated:Connect(function()
local part = tool.PrimaryPart
onActivated(tool)
--if you already set the part as primary part, if you haven't you need to refer to that part that is touching the other player (sorry for my english)
end)
remote.OnServerEvent:Connect(function(plr, pos)
local rayparams = RayCastParams.new()
rayparams.FilterDescendantInstances = {plr.Character}
rayparams.FilterType = Enum.FilterType.Exclude
local res = workspace:Raycast(handle.Position, (pos - handle.Position).Unit, params)
if not res or not res.Instance then return end
--do something with res.Instance or skip this and use mouse.Target
end)
can you please explain this part? I don’t really understand this part
Alright, so we begin the server handler by creating a RayCastParams object to filter the player character from the spatial query. We want to look for other player characters, not our own. So that’s why that exists.
Then we use WorldRoot:RayCast and as origin, we use your tool’s handle’s position. As direction we do some math to get the directional vector from a start and end point. And we pass our raycastparams object from earlier.(tldr: it draws an invisible line from the handle and returns the first part that intercepts the line)
Then we check if the spatial query succeeded by checking if the result is not null. Then we check if the instance exists(which isn’t really required, probably should be removed actually) and then you can just use result.Instance, in your other code. Because result.Instance refers to the instance the mouse was over when activate was clicked.
Generally you might add some more sanity checks before you even start the spatial query, but this is just an example so it’s fine.