Sorry for the really late reply.
You have to build a GetPartBoundsInBox query, like this:
local frontOfTheCharacter: CFrame = humanoidRootPart.CFrame + humanoidRootPart.CFrame.LookVector * 2
local sizeExtendFromOrigin: Vector3 = Vector3.new(2, 5, 2)
local objectsInArea: {Instance} = workspace:GetPartBoundsInBox(frontOfTheCharacter, sizeExtendFromOrigin, parameters)
(You can replace the last argument, “parameters”, with your own OverlapParams object)
local parameters: OverlapParams = OverlapParams.new()
parameters.FilterDescendantsInstances = {PlayersAndMobs} -- Ignore everything EXCEPT players and mobs
parameters.MaxParts = math.huge
parameters.FilterType = Enum.RaycastFilterType.Whitelist
This returns a table containing all objects that are inside this box (NOT THE PLAYER/MOB MODELS, BUT THE BODYPARTS INSIDE OF THEM)
Then, you just loop through it using pairs, ipairs or nothing at all and check if they’re valid humanoids by checking their Parent and using FindFirstChild/FindFirstChildOfClass to find a humanoid
i.e:
Change this
into
for i,v in pairs(objectsInArea) do -- look through found objects
and check for humanoids inside v’s parent
local foundHumanoid = v.Parent:FindFirstChild("Humanoid")
if foundHumanoid and foundHumanoid ~= myCharacter.Humanoid then
-- All the parry detection code and stuff in here
end
I’ve attached some code that should do the same as your script does right now, but it’s rewritten and includes some explanations for stuff
Code
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")
local m2Event = ReplicatedStorage.M2Remote.M2Fire
local PlayersAndMobs = workspace.PlayersAndMobs
local hitSound: Sound = script.Parent.HitSound
local fx: ParticleEmitter = script.fx:Clone()
m2Event.OnServerEvent:Connect(function(player)
-- Doing stuff such as 'x: number' is just assigning a type to that variable
-- i.e it declares what the variable is, in this case a number (https://luau-lang.org/typecheck)
local character: Model = player.Character
local torso: Part = character:FindFirstChild("Torso") :: Part
local humanoidRootPart: Part = character:FindFirstChild("HumanoidRootPart") :: Part
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- This is a nice way to write if statements that make the function completely stop.
-- This is just so that you don't have to wrap the entire function in one decisive if statement
if character:FindFirstChild("Blocking") then
return -- Return completely ends the function, so it won't progress anymore
end
humanoid.WalkSpeed = 3.5
-- This is basically the part of the script that uses SQ
-- Make this only loop through players and mobs
local parameters: OverlapParams = OverlapParams.new()
parameters.FilterDescendantsInstances = {PlayersAndMobs} -- Ignore everything EXCEPT players and mobs
parameters.MaxParts = math.huge
parameters.FilterType = Enum.RaycastFilterType.Whitelist
-- First, we get the position that's infront of the character's humanoid root part
local frontOfTheCharacter: CFrame = humanoidRootPart.CFrame + humanoidRootPart.CFrame.LookVector * 2
-- We calculate the size that will extend from the origin (the front of the character)
-- I'm not sure how to explain it, but if you've ever resized a part you can tell that
-- it scales from the middle
local sizeExtendFromOrigin: Vector3 = Vector3.new(2, 5, 2)
-- Then, we make a SQ request to find ALL objects that are inside that area
local objectsInArea: {Instance} = workspace:GetPartBoundsInBox(frontOfTheCharacter, sizeExtendFromOrigin, parameters)
local humanoidsFound: {Humanoid} = {} -- We will store all humanoids we find in this list.
-- This is in-case you add multi-hit
-- Using pairs/ipairs is optional now
for __, object in objectsInArea do
local opponent: Model = object.Parent
local opponentHumanoid: Humanoid = opponent:FindFirstChildOfClass("Humanoid") :: Humanoid
local opponentHumanoidRootPart: Part = opponent:FindFirstChild("HumanoidRootPart") :: Part
-- If we haven't found a humanoid, we already found this same humanoid, or this is OUR humanoid, we'll just skip to the next object
if not opponentHumanoid or table.find(humanoidsFound, opponentHumanoid) or opponentHumanoid == humanoid then
continue
end
-- Add it to the list so we don't damage this humanoid again
table.insert(humanoidsFound, opponentHumanoid)
local parryValue = opponentHumanoid:FindFirstChild("Parry")
if parryValue then
if parryValue.Value == true then
print("parried")
humanoid.WalkSpeed = 0
task.wait(10)
humanoid.WalkSpeed = 16
-- Nothing else (from what I saw) is supposed to run after this
-- So we can just use return
return
end
end
opponentHumanoid:TakeDamage(9)
hitSound:Play()
local effect = fx:Clone()
effect.Parent = opponentHumanoidRootPart
effect.CFrame = opponentHumanoidRootPart.CFrame
Debris:AddItem(effect, 0.3)
-- We get the direction of the opponent's root from the character's root, and then normalize it for easier control.
-- Using LookVector instead of this is also a way, but it could sometimes look weird. You're free to replace this with
-- humanoidRootPart.CFrame.LookVector though
local getDirectionFromCharacterAndOpponent = (opponentHumanoidRootPart.Position - humanoidRootPart.Position).Unit
humanoidRootPart:ApplyImpulse(getDirectionFromCharacterAndOpponent * 45 + Vector3.new(0, 7, 10)) -- I think you may have to tweak this a bit
task.wait(1.7)
humanoid.WalkSpeed = 16
return -- If you don't want multi-hit, keep this. Otherwise remove it
end
end)