So basically, this is how it would work in my head even though I’ve never really tried making one of those types of games before:
Make a part in studio called “HitBox” and proportion it to be around the same size as your average player, then parent that part to replicatedstorage.
Then in a client script parented to startercharacterscripts, do this:
-- Local script
local part = game.ReplicatedStorage:WaitForChild("Hitbox"):Clone()
local RE = game.ReplicatedStorage:WaitForChild("RemoteEvent")
while true do
local hitbox = workspace:GetPartBoundsInBox(character.CFrame, part.Size)
for i, part in hitbox do
if part.Parent:FindFirstChild("Humanoid") then
local tracks = part.Parent.Humanoid.Animator:GetPlayingAnimationTracks()
for i, track in tracks do
if track.Animation.AnimationId = "blahblahblah" and track.IsPlaying then
RE:FireServer(part)
end
end
end
end
task.wait()
-- Server Script
local RE = game.ReplicatedStorage.RemoteEvent
RE.OnServerEvent:Connect(function(Player, part)
if part.Parent:FindFirstChild("Humanoid") then -- Verifying info on the server
local tracks = part.Parent.Humanoid.Animator:GetPlayingAnimationTracks()
for i, track in tracks do
if track.Animation.AnimationId = "blahblahblah" and track.IsPlaying then
Player.Character.Humanoid.Health -= 20
end
end
end)
Ok just figured out I can use an event when the player clicks a button instead of while loop silly chicken, then just raycast from all players. and check if like the distance between em is like less than 2 studs and do my stuff.
i mean it’s a great way ngl, but here’s a revised version
*** Local Script (StarterCharacterScripts)***
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local part = game.ReplicatedStorage:WaitForChild("HitBox"):Clone()
local RE = game.ReplicatedStorage:WaitForChild("RemoteEvent")
-- Ensure hitbox part is not collidable and is invisible
part.CanCollide = false
part.Transparency = 1
part.Parent = workspace
while true do
part.CFrame = character.HumanoidRootPart.CFrame -- Align hitbox with the character
local hitbox = workspace:GetPartBoundsInBox(part.CFrame, part.Size)
for _, hitPart in pairs(hitbox) do
if hitPart.Parent:FindFirstChild("Humanoid") then
local humanoid = hitPart.Parent.Humanoid
local tracks = humanoid.Animator:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.AnimationId == "blahblahblah" and track.IsPlaying then
RE:FireServer(hitPart)
end
end
end
end
task.wait(0.1) -- Wait for a short period to prevent performance issues
end
and for the
1. Server Script (ServerScriptService)
local RE = game.ReplicatedStorage:WaitForChild("RemoteEvent")
RE.OnServerEvent:Connect(function(player, hitPart)
if hitPart.Parent:FindFirstChild("Humanoid") then -- Verifying info on the server
local humanoid = hitPart.Parent.Humanoid
local tracks = humanoid.Animator:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.AnimationId == "blahblahblah" and track.IsPlaying then
player.Character.Humanoid.Health -= 20
end
end
end
end)
Explanation of Improvements:
Align Hitbox to Character:
The hitbox part is aligned with the character’s HumanoidRootPart each loop iteration.
Prevent Performance Issues:
A short wait period (task.wait(0.1)) is added to prevent performance issues due to the infinite loop running without any delay.
Ensure Hitbox Part is Non-collidable and Invisible:
The hitbox part is set to non-collidable and fully transparent to ensure it doesn’t interfere with gameplay.
Consistent Naming and Pairs Iteration:
Used pairs for iterating through arrays to ensure consistency and avoid potential issues with unexpected key values.
Correct Animation ID Check:
Fixed the conditional check to == for comparing the animation ID instead of = which is used for assignment.
Make sure the HitBox part exists in ReplicatedStorage and the RemoteEvent is also set up properly in ReplicatedStorage. This setup should work better for detecting hitboxes and handling the hit detection logic. goodluck making ur game
Thanks for that, I appreciate you took tons of time to do that just to help me! But I realised I don’t need to use a while loop at all. As for a combat game I can just detect when the player uses the tool such as a punch tool. Then just raycast and check if the distance between the player and other players is 2 studs. If it is? Boom, do my stuff. Which is way better for performance and above everything else.
Thanks aswell, but that was just because this script isn’t one I put in my actual game. I just typed it up on the devforum topic and didn’t see the errors as they aren’t highlighted lol.
i don’t have anything to do anyway lol, but, you’re welcome,so uhm here’s the scripts:
Local Script (inside the Tool):
local tool = script.Parent
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local RE = game.ReplicatedStorage:WaitForChild("RemoteEvent")
local function onActivated()
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
-- Define the ray
local rayOrigin = humanoidRootPart.Position
local rayDirection = humanoidRootPart.CFrame.LookVector * 2 -- 2 studs ahead
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
local hitPart = raycastResult.Instance
if hitPart and hitPart.Parent:FindFirstChild("Humanoid") then
local humanoid = hitPart.Parent.Humanoid
local tracks = humanoid.Animator:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.AnimationId == "blahblahblah" and track.IsPlaying then
RE:FireServer(hitPart)
end
end
end
end
end
end
tool.Activated:Connect(onActivated)
Server Script (ServerScriptService)
The server script remains largely unchanged but ensures validation when the event is fired from the client.
local RE = game.ReplicatedStorage:WaitForChild("RemoteEvent")
RE.OnServerEvent:Connect(function(player, hitPart)
if hitPart.Parent:FindFirstChild("Humanoid") then -- Verifying info on the server
local humanoid = hitPart.Parent.Humanoid
local tracks = humanoid.Animator:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.AnimationId == "blahblahblah" and track.IsPlaying then
player.Character.Humanoid.Health -= 20
end
end
end
end)
Explanation:
Raycasting:
When the tool is activated (tool.Activated:Connect(onActivated)), a ray is cast from the player’s HumanoidRootPart in the direction the character is facing.
The ray has a length of 2 studs (humanoidRootPart.CFrame.LookVector * 2).
Raycast Parameters:
We use RaycastParams to ignore the character casting the ray.
Hit Detection:
If the ray hits a part and the part’s parent has a Humanoid, it checks if the specified animation is playing and then fires the remote event to the server.
Server Validation:
The server script validates the hit to ensure it’s legitimate before applying damage.
plus that was a really good choice for using a tool
Nah man you didn’t have to do that for me, I would’ve been able to do that myself lol. I’m not gonna take your script as I usually prefer to do things myself instead of stealing whole systems but I appreciate the help and I’ll mark you as the solution anyway for anyone else who is thinking about a combat game and hitbox detection stuff as it’s pretty detailed.