Something I’m confused about is coding good combat currently the way I coded it is I’m letting the client handle making the hitbox and detecting when it hits the opponent and if it does hit I’ll do any vfx stuff and then fireserver and I pass the size and position of the opponents hurtbox and check to make sure it’s correct on the server I just compare what the client sent with the actual thing to help prevent an exploiter from adjusting size and then I check if the opponent is blocking if not then deal damage but now what do I do from here? Do I FireAllClients or just the client of the person being hit so I can do any vfx stuff for them? So yeah basically this is how I setup my code, but I really wanna make it better so looking for some help. Sorry for the huge wall of code decided to share everything for combat.
client code
local function HitboxFunc(Hitbox,Move)
local TouchingParts = Hitbox:GetTouchingParts()
for _,Part in pairs(TouchingParts) do
if Part.Parent ~= Main.Character and Part.Parent:FindFirstChild("HurtBox") then
Connections["Hitbox"]:Disconnect()
local Target = Part.Parent
warn(Target.Name.." has been hit")
local TargetHurtboxSize = Target.HurtBox.Size
local TargetHurtboxPos = Target.HurtBox.Position
----> Hit Sound
--local Sound = Instance.new("Sound")
--Sound.SoundId = "rbxassetid://7148420114"
--Sound.PlayOnRemove = true
--Sound.Parent = workspace
--Sound:Destroy()
----> Hit FX
--local HitParticle = workspace.Model["Hit Particle"]:Clone()
--HitParticle.CFrame = Target.UpperTorso.CFrame
--HitParticle.Parent = workspace.Game.FX
--HitParticle.ParticleEmitter1:Emit(1)
--HitParticle.ParticleEmitter2:Emit(1)
--game.Debris:AddItem(HitParticle,0.3)
if not Target:FindFirstChild("IsBlocking") then
--> Reaction Animation
local Animator = Target.Humanoid.Animator
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://7168712174"
local Reaction = Animator:LoadAnimation(Animation)
Reaction:Play()
end
Main.Remotes.Damage:FireServer(Move.Name,Target,TargetHurtboxSize,TargetHurtboxPos)
break
end
end
Connections["Hitbox"]:Disconnect()
end
function Combat:MoveInputted(Move)
--| Makes the hitbox part
Hitbox = MakePart(HitboxSize,Main.HRP.Position+Vector3.new(HitboxPos1*FD,HitboxPos2,0),Rotation,"Hitbox",FD)
Connections["Hitbox"] = Hitbox.Touched:Connect(function(Hit)
HitboxFunc(Hitbox,Move)
end)
end
Server Code
Main.Remotes.Damage.OnServerEvent:Connect(function(Player,MoveName,Target,TargetHurtboxSize,TargetHurtboxPos)
--| Anti-cheat kind of?
--| checks if the sent size and position of the hurtbox is different from the one on the server
if (typeof(TargetHurtboxSize) == "Vector3") and (typeof(TargetHurtboxPos) == "Vector3") then
--> Check to make sure the hitboxes wasnt messed with I guess
local RealTargetHurtbox = Target.HurtBox
local RealDistance = (Target.HumanoidRootPart.Position - RealTargetHurtbox.Position).Magnitude
local Distance = (Target.HumanoidRootPart.Position - TargetHurtboxPos).Magnitude
if RealTargetHurtbox.Size ~= TargetHurtboxSize or Distance > 1.5 then
--Player:Kick("Tampering with hurtboxes detected")
warn("KICK")
end
end
TimeSinceLastHit[Target.Name] = os.clock() --> Reset the targets last hit value
if not Target:FindFirstChild("IsBlocking") then
if not Hits[Player.Name] then
Hits[Player.Name] = {TimeSinceHit = os.clock(),Hits = 0}
end
Hits[Player.Name].TimeSinceHit = os.clock()
Hits[Player.Name].Hits += 1 --> Increase their hits
if Hits[Player.Name].Hits >= 2 then --> Update their intvalue
if Player.Character:FindFirstChild("Hits") then
Player.Character.Hits.Value = Hits[Player.Name].Hits
end
end
local Moveset = require(Main.RepStorage.Modules.Client.Moveset)
for _,Data in pairs(Moveset) do
if Data.Name == MoveName then
local Damage = Data.Damage --> How much damage the move does
local Stun = Data.Stun --> How much stun the move does
--Target.Stun.Value += Stun --> Increase the targets stun value
--Main.Remotes.FX:FireAllClients(Target,"Hit") --> runs the "hit" fx for the client
Target.Humanoid:TakeDamage(Damage) --> Deal damage
--Main.Remotes.Damage:FireAllClients()
--if Data.FX then
-- Main.Remotes.FX:FireAllClients(nil,Data.FX) --> runs specific fx if the move has one
--end
break
end
end
end
end)