Hey devs!
I recently added a combat system in into my roblox game. Instead of using fists, though, the player will use swords to fight other players.
Here is a little demo:
Here is the code that I have for the system right now:
Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
local debounce = false
local walkAnimationId = "rbxassetid://ID"
local walkTrack
local idleAnimationId = "rbxassetid://ID"
local idleTrack
local swingIndex = 1
local swingAnimations = {
"rbxassetid://ID", -- DPEM1
"rbxassetid://ID", -- DPEM2
"rbxassetid://ID", -- DPEM3
"rbxassetid://ID" -- DPEM4
}
local baseDamage = 10
local bigSwingDamage = 30
local isSwinging = false
local swingConnection = nil
function Create(ty)
return function(data)
local obj = Instance.new(ty)
for k, v in pairs(data) do
if type(k) == 'number' then
v.Parent = obj
else
obj[k] = v
end
end
return obj
end
end
local BaseUrl = "rbxassetid://"
Players = game:GetService("Players")
Debris = game:GetService("Debris")
RunService = game:GetService("RunService")
Damage = baseDamage
Sounds = {
Slash = Handle:WaitForChild("SwordSlash"),
Unsheath = Handle:WaitForChild("Unsheath")
}
ToolEquipped = false
for i, v in pairs(Handle:GetChildren()) do
if v:IsA("ParticleEmitter") then
v.Rate = 20
end
end
Tool.Enabled = true
function IsTeamMate(Player1, Player2)
return (Player1 and Player2 and not Player1.Neutral and not Player2.Neutral and Player1.TeamColor == Player2.TeamColor)
end
function TagHumanoid(humanoid, player)
local Creator_Tag = Instance.new("ObjectValue")
Creator_Tag.Name = "creator"
Creator_Tag.Value = player
Debris:AddItem(Creator_Tag, 2)
Creator_Tag.Parent = humanoid
end
function UntagHumanoid(humanoid)
for i, v in pairs(humanoid:GetChildren()) do
if v:IsA("ObjectValue") and v.Name == "creator" then
v:Destroy()
end
end
end
local function GivePushback(character, magnitude)
local bv = Instance.new("BodyVelocity", character:FindFirstChild("HumanoidRootPart"))
bv.MaxForce = Vector3.new(10000000,10000000,10000000)
bv.Velocity = character.HumanoidRootPart.CFrame.LookVector * -magnitude
Debris:AddItem(bv, 0.1)
end
local touchCooldown = 0.2
local lastTouchTime = 0
function Blow(Hit)
if not Hit or not Hit.Parent or not CheckIfAlive() or not ToolEquipped or not isSwinging then
return
end
local currentTime = tick()
if currentTime - lastTouchTime < touchCooldown then
return
end
lastTouchTime = currentTime
local character = Hit.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid")
if Hit:IsDescendantOf(character) and humanoid then
if character == Character then
return
end
if humanoid then
local player = Players:GetPlayerFromCharacter(character)
if player and (player == Player or IsTeamMate(Player, player)) then
return
end
if Player:WaitForChild("IsSafe").Value == true then
return
end
UntagHumanoid(humanoid)
TagHumanoid(humanoid)
humanoid:TakeDamage(Damage)
local knockbackMagnitude = swingIndex == 4 and 100 or 50
GivePushback(character, knockbackMagnitude)
end
end
end
function Attack()
Sounds.Slash:Play()
local swingAnim = swingAnimations[swingIndex]
local anim = Instance.new("Animation")
anim.AnimationId = swingAnim
local track = Humanoid:LoadAnimation(anim)
track:Play()
isSwinging = true
if swingIndex == 4 then
Damage = bigSwingDamage
else
Damage = baseDamage
end
swingIndex = swingIndex % #swingAnimations + 1
if swingConnection then
swingConnection:Disconnect()
end
swingConnection = Handle.Touched:Connect(function(hit)
if isSwinging then
Blow(hit)
isSwinging = false
end
end)
end
Tool.Enabled = true
LastAttack = 0
function Activated()
if debounce == false then
debounce = true
if not Tool.Enabled or not ToolEquipped or not CheckIfAlive() then
return
end
Tool.Enabled = false
Attack()
LastAttack = RunService.Stepped:Wait()
Damage = baseDamage
Tool.Enabled = true
task.wait(0.75)
debounce = false
end
end
function CheckIfAlive()
return (((Player and Player.Parent and Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Torso and Torso.Parent) and true) or false)
end
function Equipped()
Character = Tool.Parent
Player = Players:GetPlayerFromCharacter(Character)
Humanoid = Character:FindFirstChildOfClass("Humanoid")
Torso = Character:FindFirstChild("Torso") or Character:FindFirstChild("HumanoidRootPart")
if not CheckIfAlive() then
return
end
ToolEquipped = true
Sounds.Unsheath:Play()
local walkAnimation = Instance.new("Animation")
walkAnimation.AnimationId = walkAnimationId
walkTrack = Humanoid:LoadAnimation(walkAnimation)
local idleAnimation = Instance.new("Animation")
idleAnimation.AnimationId = idleAnimationId
idleTrack = Humanoid:LoadAnimation(idleAnimation)
if Humanoid.MoveDirection.Magnitude > 0 then
walkTrack:Play(0.2)
end
Humanoid.Running:Connect(function(speed)
if speed > 0 and walkTrack and not walkTrack.IsPlaying then
idleTrack:Stop(0.2)
walkTrack:Play(0.2)
elseif speed == 0 and walkTrack and walkTrack.IsPlaying then
walkTrack:Stop(0.2)
idleTrack:Play(0.2)
end
end)
end
function Unequipped()
ToolEquipped = false
if walkTrack then
walkTrack:Stop(0.2)
walkTrack = nil
end
if idleTrack then
idleTrack:Stop(0.2)
idleTrack = nil
end
if swingConnection then
swingConnection:Disconnect()
end
if Humanoid and Humanoid.RigType == Enum.HumanoidRigType.R6 then
local Animator = Humanoid:FindFirstChildOfClass("Animator")
if Animator then
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
end
end
end
Tool.Activated:Connect(Activated)
Tool.Equipped:Connect(Equipped)
Tool.Unequipped:Connect(Unequipped)
As you probably saw in the video, the system is a little glitchy. The player needs to swing multiple times to hit. Do you guys know a way I can fix this? Maybe a way I can improve the system (the hitbox)?
Thanks
-DarkPurpleElixr.