I’m fairly sure this is simply a replication bug on roblox end but if the stand is controlled by a player this can be easily fixed by moving the hitboxing to the clientside and utilizing proper server sanity checks. This would make your stand gameplay much more responsive in turn for a little bit more work serversided. Refer to a the knife posts examples above if you need some examples of sanity checking.
Okay, I can try making combat client-sided. Any idea how to replicate this to other players? I’m a little new to client-sided and server-sided stuff…
Well, you can possibly keep the stand as it is on the server side, but keep the hit detection logic on the client side. Whenever you (the player) commands the stand to attack, the client will also take care of the hit detection (so this means using raycasthitbox on a client’s localscript). Once the stand gets a hit in the localscript, you can use a RemoteEvent to tell the server to damage the target that the stand hit.
Then, refer to this example post below on how the server can interpret the target. You don’t want to damage the target immediately without sanity checks. This ensures you have proper replication to all players while having adequate hitboxes.
Thank you so much, @TeamSwordphin ! You’re very generous and helpful! Here’s the final product, thanks to you:
https://gyazo.com/9416feadb6bc3f271580b132ba5e9291
dont mind that last buggy part lol…
Looking good! Happy to help and good luck on your project
Hey! I have a question about this module:
I have this sword with a few DmgPoints in it.
When I put it in StarterPack and swing it, the hitboxes work fine.
However, when I put it in ServerStorage and give it to the player via a script the tool works, but the hitboxes don’t (I turned on debug mode, lines weren’t showing up)
Any idea why this is happening?
Strange. Can i see the tool script where you initialized the Hitbox? Maybe i can catch something that you haven’t.
Hello, I upgraded the version of this module from 2.3 to 3.2 and now I am getting this error:
screenshot of code:
screenshot of error:
It seems the HitStart and HitStop methods don’t exist when I create a new hitbox. In the documentation the examples are still using the HitStart and HitStop methods so I’m guessing you didn’t remove them. Is there something obvious that I’m doing incorrectly?
Does any print messages come up in the output from RaycastHitbox? (Assuming warning messages are turned on). Are you deinitializing or destroying the hitbox anywhere?
Right when you responded I found the issue. The issue was that the CollectionService tag you have added to the object passed into the Initialize method got removed whenever I equipped it (I passed a tool into the object parameter) which caused the hitbox to deinitialize.
I don’t know why the tag got removed every time I equipped the tool but I managed to fix it by just passing in a different object that contained the DmgPoints.
Hmm that’s strange. Never had that problem when I was working with tools. As far as I know the tag is only removed when the instance you passed it in is destroyed.
Yeah, here you go:
local Players = game:GetService("Players")
local player
repeat wait(); Players:FindFirstChild(script.Parent.Parent.Name) until script.Parent.Parent:IsA("Model")
local player = Players:FindFirstChild(script.Parent.Parent.Name)
local character = player.Character or player.CharacterAdded:Wait()
while character.Parent ~= workspace do
if character.Parent ~= workspace then
character = player.Character or player.CharacterAdded:Wait()
end
game:GetService("RunService").RenderStepped:Wait()
end
local humanoid = character:WaitForChild("Humanoid")
local trail = script.Parent.Blade.Trail
local currentlyAttacking = false
local canAttack = script.Parent.canAttack
--Hitboxes--
local RS = game:GetService("ReplicatedStorage")
local RAYCAST_HITBOX = require(RS.RaycastHitboxV3)
local ignoreList = {character}
local newHitbox = RAYCAST_HITBOX:Initialize(script.Parent.Blade, ignoreList)
newHitbox.OnHit:Connect(function(hit, humanoid)
if character.RageActive.Value == true then
humanoid:TakeDamage(10 * 1.5)
else
humanoid:TakeDamage(10)
end
if hit.Name == "HeadHitbox" then
if humanoid.Health <= humanoid.MaxHealth * 1/10 then
for _, v in pairs(hit:GetChildren()) do
v:Destroy()
end
humanoid.Head:Destroy()
local blood = game.ReplicatedStorage.Blood:Clone()
blood.Parent = humanoid.Parent.Torso
end
end
end)
--Attack Functions--
function Slash()
newHitbox:HitStart()
canAttack.Value = false
currentlyAttacking = true
trail.Enabled = true
wait(0.35)
newHitbox:HitStop()
trail.Enabled = false
currentlyAttacking = false
end
function Attack()
if canAttack.Value and not currentlyAttacking then
Slash()
end
end
script.Parent.cooldownFalse.OnServerEvent:Connect(function()
canAttack.Value = true
end)
script.Parent.Activated:Connect(Attack)
The thing is that I have another tool which essentially has the same code in ServerStorage, and its given the exact same way; and only that one works.
Hmm how are you giving the tool to the player? I could not replicate the problem with the code in your post.
My tests has this one script in ServerScriptService:
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
wait(1)
game.ServerStorage.Tool:Clone().Parent = player.Backpack
end)
end)
And here’s a slightly modified version of your script for my testing (I doubt I fixed the main problem though for any edits I did)
local Players = game:GetService("Players")
local player
repeat wait(); Players:FindFirstChild(script.Parent.Parent.Name) until script.Parent.Parent:IsA("Model")
local player = Players:FindFirstChild(script.Parent.Parent.Name)
local character = player.Character or player.CharacterAdded:Wait()
while character.Parent ~= workspace do
if character.Parent ~= workspace then
character = player.Character or player.CharacterAdded:Wait()
end
game:GetService("RunService").RenderStepped:Wait()
end
local humanoid = character:WaitForChild("Humanoid")
local currentlyAttacking = false
local canAttack = script.Parent.canAttack
--Hitboxes--
local RS = game:GetService("ReplicatedStorage")
local RAYCAST_HITBOX = require(RS.RaycastHitboxV3)
local ignoreList = {character}
local newHitbox = RAYCAST_HITBOX:Initialize(script.Parent.Handle, ignoreList)
newHitbox:DebugMode(true)
newHitbox.OnHit:Connect(function(hit, humanoid)
print(hit)
end)
--Attack Functions--
function Slash()
newHitbox:HitStart()
canAttack.Value = false
currentlyAttacking = true
wait(0.35)
newHitbox:HitStop()
currentlyAttacking = false
canAttack.Value = true
end
function Attack()
if canAttack.Value and not currentlyAttacking then
Slash()
end
end
--- I moved canAttack.Value = true into the Slash() function
--script.Parent.cooldownFalse.OnServerEvent:Connect(function()
-- canAttack.Value = true
--end)
script.Parent.Activated:Connect(Attack)
Upon cloning and parenting the tool to the player’s backpack, the hitbox and tool work as expected. Is the RaycastModule printing anything in the output? Does it see any of the attachments in the sword?
It does indeed see the attachments, but it doesn’t create the hitbox.
Here is the giver script:
local click = script.Parent.ClickDetector
local weapon = game.ServerStorage.Longsword
click.MouseClick:Connect(function(player)
local clone = weapon:Clone()
clone.Parent = player.Backpack
local spawns = workspace.Spawns
local random = math.random(1, 8)
player.Character.HumanoidRootPart.Position = spawns["Spawn" .. random].Position
end)
I was wondering if I should use MoveTo instead of .Position because of a side issue, where the player would be outside of the arena walls on other players’ screens ignore this i just replaced it with moveto
Huh. Replacing it seems to have fixed it… for some reason.
There should be methods to change/remove the object that is being used to find the DmgPoints that is passed into the Initialize method but still keep the original object as an identifier to the hitbox. (sorry if this sounds confusing)
Could be useful if you want to make alternating hitboxes (if you have 2 parts containing DmgPoints and you want to alternate between them each attack; useful if you want to add fists into your game).
Could also be useful if you want to remove the object entirely and only use points set with SetPoints for a certain attack or something.
Sounds cool, though I feel doing something like this is more adequate than shoving more convoluted features on hitboxes (and you can further simplify this with a hitbox wrapper which doesn’t take too long either):
local fist_hitboxes = {leftArm:Initialize(leftArm, {char}), rightArm:Initialize(rightArm, {char})}
local currentHitbox = fist_hitboxes[1]
currentHitbox:HitStart()
wait(1)
currentHitbox:HitStop()
currentHitbox = fist_hitboxes[2]
currentHitbox:HitStart()
wait(1)
currentHitbox:HitStop()
And I do like the SetPoints idea where it doesn’t need an object, perhaps using a vector point in space instead.
Would i be able to use humanoid and part detection at once? I want my sword to detect another sword’s blade, Or detect a part so it stops the swing like in mordhau.
(For what i’m making, I want a bottle that you can hit people with, But if you hit a part it breaks and deals more damage.)
Using part detection will no longer check for humanoids automatically. Doesn’t mean it no longer works, it just means you will have to check it yourself.
local hitbox = raycastHitbox:Initialize (object, ignoreList)
hitbox:PartMode(true)
hitbox.OnHit:Connect(function (hit)
if hit.Parent:FindFirstChildOfClass("Humanoid") then
end
if hit.Name == "Blade" then
end
end)
Oh, I see, Thank you very much!
Hey I was wondering how would this be used for Melee combat uses? (fist), I just cannot seem to understand it.
Sorry if you’ve already answered this question, I didn’t see!