Um, near halloween, maybe?
NEW TUTORIAL DROPS ON THE 14TH (v day)!!
View Post for the old tutorial.
THERE ARE SOME ERRORS IN THE CODE WHERE I USE Humanoid:LoadAnimation() INSTEAD OF Humanoid.Animator:LoadAnimation(). HOWEVER THESE METHODS STILL WORK BUT CAN RESULT IN CODE MAYBE NOT WORKING PROPERLY.
Hello!
We will be teaching you how to make a advanced sword combat system.
But what is a combat system?
A combat system is that it includes punching, swords, or and can deal damage. These systems are usally found in games eg: ZOAssets Required
Lets get started!
WARNING: Very long tutorial. Please make sure you did everything correctly.
Step 1 -- Making the sword model and the basics of Welding
So you've all seen your tools fall down like a cracker, right?Say no more! Ungroup the model, drag it in the tool, DONT MOVE anything or else it will break!
And rename Meshes/Katana_Cube
to Handle
or you got no tool lol
Make a WeldConstraint
in the tool then set Part0
to the Instance Handle
and Part1
to the Instance Meshes/Katana_Cube.001
Play around with the name of Meshes/Katana_Cube.001
, it wont break.
However, you might end up getting this, dont do anything else
Step 2: Animations
Paste a LocalScript in your tool, then make a folder named Sword then make another folder in it called "Animations". Put "Sword" in repliactedstorage! If it takes up too much time, write the following code in the command bar:local memefolder = Instance.new("Folder", funnifolder) memefolder.Name = "Animations"
Now, you should end up with this
Paste the code in your tool:
local Tool = script.Parent
local Player = game.Players.LocalPlayer
local Char = game.Workspace:WaitForChild(Player.Name)
local RS = game.ReplicatedStorage
local Humanoid = Char:WaitForChild("Humanoid")
local Check = 0
local Enable = true
print (Player.Name)
Tool.Activated:Connect(function()
local humanoid = script.Parent.Parent:WaitForChild("Humanoid")
if Enable == true then
Enable = false
if Check == 0 then
humanoid:LoadAnimation(RS.Sword.Animations["1"]):Play()
wait(0.5)
Check = 1
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 1 then
humanoid:LoadAnimation(RS.Sword.Animations["2"]):Play()
wait(0.5)
Check = 2
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 2 then
humanoid:LoadAnimation(RS.Sword.Animations["3"]):Play()
wait(0.5)
Check = 0
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
end
end
end
end
end)
while wait(5) do
if Check == 1 or Check == 2 then
Check = 0
end
end
(decided to go crazy with coding)
" but it keeps saying “1 is not a vaild member of RepliactedStorage”
real mature
Make 4 animations in repliacted storage saying as the first one, 1
Then the second one, 2
Then the third one, 3
Then the fourth one, 4
Upload only animations Slash1, Slash2, Slash3, and Slash4, but DO NOT publish any more.
Now, paste Slash1’s animation asset ID in the Animations Folder 1 Animation Id → RepliactedStorage.Sword.Animations.1.AnimationId
Then, paste Slash2’s animation asset ID in the Animations Folder 2 Animation Id → RepliactedStorage.Sword.Animations.2.AnimationId
Then, paste Slash3’s animation asset ID in the Animations Folder 3 Animation Id → RepliactedStorage.Sword.Animations.3.AnimationId
Finally, paste Slash4’s animation asset ID in the Animations Folder 4 Animation Id–> RepliactedStorage.Sword.Animations.4.AnimationId
But you’ll end up with this:
Thats because we didnt add RemoteEvents!
Run the following in your cmd bar:
local memefolder = Instance.new("Folder", game.ReplicatedStorage.Sword) memefolder.Name = "Remotes"
local Slash = Instance.new("RemoteEvent", memefolder)
Slash.Name = "Slashing"
You should get this:
Now, update the Animation code:
local Tool = script.Parent
local Player = game.Players.LocalPlayer
local Char = game.Workspace:WaitForChild(Player.Name)
local RS = game.ReplicatedStorage
local Humanoid = Char:WaitForChild("Humanoid")
local Check = 0
local Enable = true
print (Player.Name)
Tool.Activated:Connect(function()
local humanoid = script.Parent.Parent:WaitForChild("Humanoid")
if Enable == true then
Enable = false
if Check == 0 then
humanoid:LoadAnimation(RS.Sword.Animations["1"]):Play()
RS.Sword.Remotes.Slashing:FireServer(script.Parent.Handle)
wait(0.5)
Check = 1
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 1 then
humanoid:LoadAnimation(RS.Sword.Animations["2"]):Play()
RS.Sword.Remotes.Slashing:FireServer(script.Parent.Handle)
wait(0.5)
Check = 2
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 2 then
humanoid:LoadAnimation(RS.Sword.Animations["3"]):Play()
RS.Sword.Remotes.Slashing:FireServer(script.Parent.Handle)
wait(0.5)
Check = 0
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
end
end
end
end
end)
while wait(5) do
if Check == 1 or Check == 2 then
Check = 0
end
end
Woohoo! You just got your slash animations:
And now, let’s add a idle animation.
Make a Animation in ReplicatedStorage → Sword → Animations and call it “Idle”
And then, make a localscript in the tool with the code:
script.Parent.Equipped:Connect(function()
animation = game.Players.LocalPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Sword.Animations.Idle)
animation:Play()
print("playing idle")
end)
script.Parent.Unequipped:Connect(function()
animation:Stop()
print("unequip detected, stopped animation")
end)
script.Parent.Activated:Connect(function()
animation:Stop()
wait (9)
animation:Play()
print ("animation is playing again")
end)
Step 3: Creating the Equip Animations
Open your animations dummy with Animation Editor, then open "SwordEquip" After that, publish it to roblox and make a animation in ReplicatedStorage,Sword, then Animations. Name it "Equip_And_UnEquip", and paste the Equip Animation there.Now put a LocalScript in your tool and name it “EquipAnimations”
The localscript’s code should be:
--This code is mine! So i didnt steal this entire code.
local Tool = script.Parent
local function onEquipped(_mouse)
local animation = game.Players.LocalPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Sword.Animations.Equip_And_UnEquip)
animation:Play()
end
Tool.Equipped:Connect(onEquipped)
Tool.Unequipped:Connect(function()
local animation = game.Players.LocalPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Sword.Animations.Equip_And_UnEquip)
animation:Play(0.100000001, 1, -1) -- Reverses Animation
end)
Now, we need to make our sword damage others. I’ll cover this in Step 4.
Step 4: Damaging the player
We need to search for a humanoid if the otherpart finds one, then uses the TakeDamage function. (Script below is not mine)local tool = script.Parent
local canDamage = false
local function onTouch(otherPart)
local humanoid = otherPart.Parent:FindFirstChild("Humanoid")
local hrp = otherPart.Parent:FindFirstChild("HumanoidRootPart")
if not humanoid then
return
end
if humanoid.Parent ~= tool.Parent and canDamage then
humanoid:TakeDamage(10)
else
return
end
canDamage = false
end
local function slash()
local str = Instance.new("StringValue")
str.Name = "toolanim"
str.Value = "Slash"
str.Parent = tool
canDamage = true
end
tool.Activated:Connect(slash)
tool.Handle.Touched:Connect(onTouch)
Woohoo! You just made your first advanced sword combat!
But theres something missing.
Wanna control the damage value with a IntValue? Say no more!
Insert a “Configuration” in the, ( you know what i’m gonna say), ReplicatedStorage, then Sword.
Then, add a IntValue saying Damage and update the code you just wrote:
local tool = script.Parent
local canDamage = false
local function onTouch(otherPart)
local humanoid = otherPart.Parent:FindFirstChild("Humanoid")
local hrp = otherPart.Parent:FindFirstChild("HumanoidRootPart")
if not humanoid then
return
end
if humanoid.Parent ~= tool.Parent and canDamage then
humanoid:TakeDamage(game.ReplicatedStorage.Sword.Configuration.Damage.Value)
else
return
end
canDamage = false
end
local function slash()
local str = Instance.new("StringValue")
str.Name = "toolanim"
str.Value = "Slash"
str.Parent = tool
canDamage = true
end
tool.Activated:Connect(slash)
tool.Handle.Touched:Connect(onTouch)
Step 5: The sounds --Lets make some music!
It seems quiet in your lonely area-- why not some SOUNDS?!?!https://www.roblox.com/library/10914398099/things
From the model up top, get it and remove the particles.
Keep the following:
Drag them all into the Sounds Folder in the Sword Folder in replicated storage, then update the animation code with this:
local Tool = script.Parent
local Player = game.Players.LocalPlayer
local Char = game.Workspace:WaitForChild(Player.Name)
local RS = game.ReplicatedStorage
local Humanoid = Char:WaitForChild("Humanoid")
local Check = 0
local Enable = true
print (Player.Name)
Tool.Activated:Connect(function()
local humanoid = script.Parent.Parent:WaitForChild("Humanoid")
if Enable == true then
Enable = false
if Check == 0 then
humanoid:LoadAnimation(RS.Sword.Animations["1"]):Play()
local swing = RS.Sword.Sounds.SwingSharp1:Clone()
swing.Parent = game.Workspace
swing:Play()
game.Debris:AddItem(swing,5)
wait(0.5)
Check = 1
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 1 then
humanoid:LoadAnimation(RS.Sword.Animations["2"]):Play()
local swing = RS.Sword.Sounds.SwingSharp1:Clone()
swing.Parent = game.Workspace
swing:Play()
game.Debris:AddItem(swing,5)
wait(0.5)
Check = 2
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
else if Check == 2 then
humanoid:LoadAnimation(RS.Sword.Animations["3"]):Play()
local swing = RS.Sword.Sounds.SwingSharp1:Clone()
swing.Parent = game.Workspace
swing:Play()
game.Debris:AddItem(swing,5)
wait(0.5)
Check = 0
print (Check) --However, we make sure that is it working normally by printing the Check value inside of the script.
Enable = true
end
end
end
end
end)
while wait(5) do
if Check == 1 or Check == 2 then
Check = 0
end
end
Step 6 --Your FX
It just dosen't give out the feel, why not change that with some FX?Make a part (should look like this)
Add a attachment, then a particle emitter inside of it
Change the texture to rbxassetid://7185003058 and set the speed to 0.
Change the size to this by clicking on the three dots and try to get the size accurate to the one below.
Set the lifetime to 0.25, the Rate to 1, and your done
Now, make a folder in the sword saying “FX” and drag the attachment in there. You will see
Dont worry! Take the Particle out of the attachment, then drag it in. Name it “HitFX”
Now, set the rate to 0 as we are gonna be using :Emit() and we dont want to get it stuck on the player.
Update the damage script code with the following:
local tool = script.Parent
local canDamage = false
local function onTouch(otherPart)
local humanoid = otherPart.Parent:FindFirstChild("Humanoid")
local hrp = otherPart.Parent:FindFirstChild("HumanoidRootPart")
if not humanoid then
return
end
if humanoid.Parent ~= tool.Parent and canDamage then
humanoid:TakeDamage(1)
local slash = game.ReplicatedStorage.Sword.Sounds.Slash3:Clone()
slash.Parent = hrp
slash:Play()
local hrpattachment = Instance.new("Attachment", hrp)
local fx = game.ReplicatedStorage.Sword.FX.HitFX:Clone()
fx.Parent = hrpattachment
fx:Emit(1)
game.Debris:AddItem(hrpattachment, 3)
game.Debris:AddItem(slash, 6)
else
return
end
canDamage = false
end
local function slash()
local str = Instance.new("StringValue")
str.Name = "toolanim"
str.Value = "Slash"
str.Parent = tool
canDamage = true
end
tool.Activated:Connect(slash)
tool.Handle.Touched:Connect(onTouch)
Then, make two attachments positioned like this on the blade:
Add an trail onto it and name it “SwordTrail”
Set the Attachment0 to the first attachment you just made, and the Attachment1 to the second one you made on the blade.
The texture dosen’t look very nice, so grab out the sword trail texture (7509141236) and paste it in the “Texture” box.
As you can see-- It’s lasting forever! Change the lifetime in the lifetime trail box to 0.2
And finally, set the Enabled property of the trail to false. It will turn back on when we slash
Make another localscript and paste the code in the localscript:
script.Parent.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
script.Parent.Handle.SwordTrail.Enabled = true
wait (0.2)
script.Parent.Handle.SwordTrail.Enabled = false
end)
end)
Voila! Your first ever advanced sword combat is finished! Progress:
(this took me 3 hours to write)