I’m using Raycast Hitbox 4.01 for my sword, the cooldown for the sword is an attribute, and the animation needs to be completed to strike again. The issue with it is that to save memory I want to use the function HitStop() which stops the hitbox from working after the animation is played. The issue with this is that the animation is played on the client so I can’t track if it is completed or not.
How should I go about doing this?
Local Script
local player = game.Players.LocalPlayer
local tool = script.Parent
local remoteEvent = tool:WaitForChild("HitDetection")
local char = player.Character
local humanoid = char:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local slashAnimation1 = Instance.new("Animation")
slashAnimation1.AnimationId = "rbxassetid://15699217139"
local slashAnimation2 = Instance.new("Animation")
slashAnimation2.AnimationId = "rbxassetid://15699432438"
local cooldown = false
local swingSpeed = tool:GetAttribute("swingSpeed")
tool.Activated:Connect(function()
if not cooldown then
cooldown = true
local randomAttack = math.random(1, 2)
local anim
if randomAttack == 1 then -- slash1
anim = animator:LoadAnimation(slashAnimation1)
anim:Play()
remoteEvent:FireServer(randomAttack)
elseif randomAttack == 2 then
anim = animator:LoadAnimation(slashAnimation2)
anim:Play()
remoteEvent:FireServer(randomAttack)
end
anim.Stopped:Wait()
task.wait(swingSpeed)
cooldown = false
end
end)
Server Script
local tool = script.Parent
local handle = tool:WaitForChild("Handle")
local char = tool.Parent
local remoteEvent = tool:WaitForChild("HitDetection")
local replicatedStorage = game:GetService("ReplicatedStorage")
local raycastHitboxModule = require(replicatedStorage:WaitForChild("RaycastHitboxV4"))
local hitBox = raycastHitboxModule.new(handle)
hitBox.RaycastParams = RaycastParams.new()
hitBox.RaycastParams.FilterDescendantsInstances = {char}
hitBox.RaycastParams.FilterType = Enum.RaycastFilterType.Exclude
local damage = 17
local lungeDamage = 30
local connection
remoteEvent.OnServerEvent:Connect(function(player, attackType)
hitBox:HitStart()
char = tool.Parent
hitBox.RaycastParams = RaycastParams.new()
hitBox.RaycastParams.FilterDescendantsInstances = {char}
hitBox.RaycastParams.FilterType = Enum.RaycastFilterType.Exclude
connection = hitBox.OnHit:Connect(function(hit, humanoid)
print(attackType)
if attackType == 1 then
humanoid:TakeDamage(damage)
elseif attackType == 2 then
humanoid:TakeDamage(damage)
end
hitBox:HitStop()
end)
end)
I highly suggest detecting hits on the client and then verifying the hit on the server to prevent exploits. If your hitbox is on the server, landing hits will feel laggy and inaccurate.
Everything is exploitable. Don’t try to make your “anti-exploit” thing perfect, it’ll just do more problems on the player side.
You can use 1 remote and just send different information, like remote:FireServer(“Stop”) or remote:FireServer(“Start”) and then remote.OnServerEvent(player, hitboxState) if hitboxState == “Start” then hitbox:HitStart() and etc. you get it
Alright, so I called the function on the client instead of the server but I keep getting this error.
07:56:55.900 Workspace.Swords.Linked Sword.Functionality:20: attempt to call missing method 'Connect' of table - Server - Functionality:20
07:56:55.900 Stack Begin - Studio
07:56:55.900 Script 'Workspace.Swords.Linked Sword.Functionality', Line 20 - Studio - Functionality:20
07:56:55.900 Stack End - Studio
Server
local connection
remoteEvent.OnServerEvent:Connect(function(player, attackType, hitBox)
char = tool.Parent
hitBox.RaycastParams = RaycastParams.new()
hitBox.RaycastParams.FilterDescendantsInstances = {char}
hitBox.RaycastParams.FilterType = Enum.RaycastFilterType.Exclude
connection = hitBox.OnHit:Connect(function(hit, humanoid)
if attackType == 1 then
humanoid:TakeDamage(damage)
elseif attackType == 2 then
humanoid:TakeDamage(damage)
end
hitBox:HitStop()
end)
end)
Client
local replicatedStorage = game:GetService("ReplicatedStorage")
local raycastHitboxModule = require(replicatedStorage:WaitForChild("RaycastHitboxV4"))
local hitBox = raycastHitboxModule.new(handle)
hitBox.RaycastParams = RaycastParams.new()
hitBox.RaycastParams.FilterDescendantsInstances = {char}
hitBox.RaycastParams.FilterType = Enum.RaycastFilterType.Exclude
tool.Activated:Connect(function()
if not cooldown then
cooldown = true
local randomAttack = math.random(1, 2)
local anim
if randomAttack == 1 then -- slash1
hitBox:HitStart()
anim = animator:LoadAnimation(slashAnimation1)
anim:Play()
remoteEvent:FireServer(randomAttack, hitBox)
elseif randomAttack == 2 then
hitBox:HitStart()
anim = animator:LoadAnimation(slashAnimation2)
anim:Play()
remoteEvent:FireServer(randomAttack, hitBox)
end
anim.Stopped:Wait()
task.wait(swingSpeed)
cooldown = false
end
end)
If you know how the module works, that’s the only way I can explain it, also I’m not sending “the module” to the server I’m sending the hitbox to the server. I’m managing it on the client but after I fire the remote event the server actually manages hit calculations.
You are totally sending a module function that is required on the client. Maybe you should try learning modules and remotes a bit more? Otherwise my help is gonna be worthless.
If you want lagless normal hitbox, control it on client side.
If you want less exploitable hitbox, control it on the client side and check the distance between hit and part it hit.
If you want crappy laggy but non exploitable hitbox, control it on the server side.
In your script i see that you’re for some reason trying to control your hitbox on client and server side at the same time, tell me for what?
If you still want to continue using RaycastHitbox, I suggest you remove any calling signal for RaycastHitbox as it is server-sided, as for your problem what I did was:
Play the animation and hitbox start (server only)
Validate if the player has the weapon equipped (precautionary check)
If the animation has stopped (a special wait, then disable hitbox by firing a RemoteEvent)
So would this give the client full control over the hitbox system? If it does give them any control, I didn’t realize this before but thanks for letting me know.
Instead of doing that, should I require it in the server script, use a remote function to start the hitbox on the client, and then on the server check if the hitbox detected any character model?
My goal was to have the hitbox on the client so that it wouldn’t cause a lot of server lag, then I would detect if it was hit on the server.
This is what I was attempting to go for but I’m not really sure how to execute it properly
Ah sorry my wording is not clear, I was just saying any reference to RaycastHitbox on the client even a signal should be removed as it’s only server-sided.
No what I mean here is that you play the animation on the client and fire an event that triggers hitbox start signal on the server, after the animation has stopped by using AnimationTrack.Stopped:Wait(), simply fire an event that disables this by using the hit stop signal.
That was much easier to digest! Though… the last time I tried controlling it on the server the hitbox visualized was a bit off from the attachments on the sword.
Is there any way I can solve this issue? The game may be laggy at times anyway due to you exploding a lot of parts in different maps.