I am making a fists tool with this that has a left and a right punch. I want to make this so there are two different hitboxes depending on which punch animation is being used, so I’ve created two casters and I start and stop an individual one when they’re needed. However, both casters seem to start when I intend to start only one. Is the module not supposed to be used like this, or is there a workaround?
This seems like an issue with your code. I’m not able to help you further without seeing a decently large snippet of code, but from the information at hand, it shouldn’t be an issue with the module.
What are the benefit’s for me switching to this module? Is it better for the user experience if its client side instead of server? For example, this is my current server side code for hitboxes. It might be bad but it does the job alright.
local ServerSideHandler = coroutine.wrap(function()
while task.wait(0.009) do
for i,v in pairs(AllRunningHitBoxes) do
local player = v.player
local playercharacter = v.player.Character
for i,v in pairs(workspace:GetPartsInPart(v.hitboxpart)) do
if not v:IsDescendantOf(playercharacter) then
if (tick() - PlayerStates[player.Name].M1Frame) > 0.4 then
print("hit")
PlayerStates[player.Name].M1Frame = tick()
end
end
end
end
end
end)
ServerSideHandler()
Your questions are already answered in the thread, please be more specific as to what issues you have with the module.
I found a workaround to my issue. However, an error pops up randomly and I’m wondering what it means.
https://i.imgur.com/2CMUcR4.png
Did you set AutoSetup
to false
in the Settings
table by any chance? This error should only be happening if you set it to false.
Nope, I’ve never changed the AutoSetup value. Disregard the first edit I made.
That error shouldn’t be occurring if you haven’t changed the AutoSetup value. If possible, could you provide a minimal place file in which this error occurs? It would help greatly in fixing the issue.
Updates 1.0.8.3 - 1.0.8.5
-
Added checks for if a descendant connection exists before disconnecting it.
-
Added a one-second debounce for disconnecting a remote-event connection, in order to prevent potential remote packet exhaustion. Thank you @Bizarre_Amar for the help in recognizing the issue!
-
Added a check to make sure the Caster is still enabled at the time of receiving the remote packet data.
If the Caster Owner is set to the client, you’d use this for anti-cheat.
Caster.Collided:Connect(function(Data)
if (Data.Position - Caster.Object.Position).Magnitude > 5 then
return print("very likely an exploiter")
end
end)
Is there a way to send the HitHumanoid directly to the Server since the server does the calculations to prevent exploiters? Because people can just call the remote function that sends the Hit Humanoid to the server.
Yes, hence the need for a distance-check. An exploiter could send false hit data from the client to the server, which is unwanted behavior.
If you want to also have the humanoid which was hit sent to the server, see Caster.HumanoidCollided.
I’d like to clarify on a few matters:
-
Minimizing exploitability is a pipe dream as it stands now anyway - even if you calculate hitboxes on the server, what prevents a client from simply teleporting their character around instead? If teleported at small distances around a target mob, the server won’t be able to detect it as a speed exploit.
-
As mentioned in the original post, this trades security for client responsiveness & UX, creating for more visually-accurate hitboxes.
I have a question, I am unable to make my ClientCast work properly when the client cast starts everything but the damage portion works, it’s not detecting the humanoid of other players/dummies, therefore, it’s not doing any damage. Here’s my code please let me know what I’m doing wrong?
game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
print('CharacterAdded')
local PropWep = WepFolder.PropWep:Clone()
PropWep:SetPrimaryPartCFrame(Character.UpperTorso.CFrame * CFrame.new(0,0,-0.60))
PropWep.Parent = Character
local Motor6D = Instance.new('Motor6D')
Motor6D.Name = "HandWeld"
Motor6D.Part0 = Character.PrimaryPart
Motor6D.Part1 = PropWep.PrimaryPart
Motor6D.C0 = CFrame.new(Vector3.new(0,0,0.60)) * CFrame.Angles(0,0,math.rad(45))
Motor6D.Parent = PropWep
local raycastparams = RaycastParams.new()
local Debounce = {}
raycastparams.FilterDescendantsInstances = {Character}
raycastparams.FilterType = Enum.RaycastFilterType.Blacklist
ClientCaster = ClientCast.new(PropWep, raycastparams)
local Character = Player.Character or Player.CharacterAdded:Wait()
ClientCaster.Collided:Connect(function(RaycastResult, HitHumanoid)
print('before')
if IsEquipped and debounce[HitHumanoid] then
return
end
print('After')
debounce[HitHumanoid] = true
IsEquipped = true
HitHumanoid:TakeDamage(10)
wait(0.5)
debounce[HitHumanoid] = false
IsEquipped = false
print('Swing')
end)
ClientCaster:Start()
ClientCaster:StartDebug()
end)
end)
Hello, you should be using HumanoidCollided and not Collided.
I’ve tried both ways neither work
I recommend you isolate as much of your code as possible and make a script which reproduces the issue in as little lines as possible. From there, it will be easier to see what the bug is.
I appreciate you so much for this! This is absolutely awesome. Can i ask a question? Where does this script go?
-- Call module
local ClientCast = require(PATH.ClientCast)
-- Create ClientCaster object
local Caster = ClientCast.new(workspace.Part, RaycastParams.new())
-- Connect callback to 'Collided' event
Caster.Collided:Connect(print)
-- Set owner of ClientCaster, who will be the one to calculate collisions.
-- You can skip this if you want the server to be the owner.
Caster:SetOwner(Player)
-- Start detecting collisions
Caster:Start()
i was reading your post on github and i dont really understand where to put this script at. Any help is greatly appreciated.
You can place it either in ReplicatedStorage or ServerStorage.
Forgive me if im not the smartest but if im doing it correctly:
The clientcast module script goes in “ServerStorage”
-- Call module
local ClientCast = require(PATH.ClientCast)
-- Create ClientCaster object
local Caster = ClientCast.new(workspace.Part, RaycastParams.new())
-- Connect callback to 'Collided' event
Caster.Collided:Connect(print)
-- Set owner of ClientCaster, who will be the one to calculate collisions.
-- You can skip this if you want the server to be the owner.
Caster:SetOwner(Player)
-- Start detecting collisions
Caster:Start()
this script goes in “serverstorage”
local ClientCast = require(game.ServerStorage.ClientCast)
local KillPart = Instance.new('Part')
KillPart.Anchored = true
KillPart.CanCollide = false
KillPart.CFrame = CFrame.new(0, 1, 0)
KillPart.Parent = workspace
function GenerateAttachment(Position)
local Attachment = Instance.new('Attachment')
Attachment.Name = 'DmgPoint'
Attachment.Position = Position
Attachment.Parent = KillPart
end
for X = -2, 2 do
GenerateAttachment(Vector3.new(X, Y, Z))
end
local ClientCaster = ClientCast.new(KillPart, RaycastParams.new())
local Debounce = {}
ClientCaster.HumanoidCollided:Connect(function(RaycastResult, HitHumanoid)
if Debounce[HitHumanoid] then
return
end
Debounce[HitHumanoid] = true
print('Ow!')
HitHumanoid:TakeDamage(10)
wait(0.5)
Debounce[HitHumanoid] = false
end)
ClientCaster:Start()
and this script goes in serverscriptservice i believe?
Then i just add DmgPoints as attachments.
How could i make it so that the ClientCaster can only hit 1 person instead of multiple?