You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
How can I script a combat system? Do I put a function for every individual attack, or do I have like a list of properties and then return them. Then use those properties on whatever attack it may be.
What is the issue? Include screenshots / videos if possible!
I’ve tried making a combat system, but found it tedious to keep making more and more functions for individual attacks.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have tried making a GlobalTable which has tables inside of it which store information about each attack, then sending that to the server to do the attack with the given data.
local mod = {}
function mod:AttackData()
local self = setmetatable(mod, {})
self.Name = "FirstPunch"
self.Damage = 5
self.CanBlock = true
self.AnimationId = "rbxassetid://123456789" -- Just a placeholder.
self.SoundId = "rbxassetid://123456789"
return self
end
return mod
or
local mod = {}
mod.FirstPunch = function()
-- Code here
end
mod.SecondPunch = function()
-- Code here
end
mod.FrontDash = function()
-- Code here
end
mod.Uppercut = function()
-- Code here
end
return mod
I had to have an individual remotefunction for every attack:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Functions = ReplicatedStorage:FindFirstChild("Functions")
local FirstPunchFunction = Functions:WaitForChild("FirstPunchFunction")
local SecondPunchFunction = Functions:WaitForChild("SecondPunchFunction")
local FrontDashFunction = Functions:WaitForChild("FrontDashFunction")
local UppercutFunction = Functions:WaitForChild("UppercutFunction")
I want to make a better, more convenient method of doing this.
Could I like send a table to the server during a remotefunction , then use those parameters to do different attacks in a module ? And it only requires one remote event so it’s a lot easier.
For the module script, your approach can be something like:
local Attack = {}
Attack.__index = Attack
function Attack.new(name, damage, canBlock, animationId, soundId)
local self = setmetatable({}, Attack)
self.Name = name
self.Damage = damage
self.CanBlock = canBlock
self.AnimationId = animationId:match("^rbxassetid://") and animationId or "rbxassetid://" .. animationId
self.SoundId = soundId:match("^rbxassetid://") and soundId or "rbxassetid://" .. soundId
return self
end
function Attack:Execute(player)
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChild("Humanoid")
if humanoid then
local animator = humanoid:FindFirstChild("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = humanoid
end
local animation = Instance.new("Animation")
animation.AnimationId = self.AnimationId
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
end
local sound = Instance.new("Sound")
sound.SoundId = self.SoundId
sound.Parent = character
sound:Play()
sound.Ended:Connect(function()
sound:Destroy()
end)
end
return Attack
And for the local script it can be:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Attack = require(ReplicatedStorage:WaitForChild("Attack"))
local firstPunch = Attack.new("FirstPunch", 5, true, "123456789", "9125786547")
local secondPunch = Attack.new("SecondPunch", 10, false, "0123456789", "9125786547")
local function onKeyPress(input)
if input.KeyCode == Enum.KeyCode.One then
firstPunch:Execute(Players.LocalPlayer)
elseif input.KeyCode == Enum.KeyCode.Two then
secondPunch:Execute(Players.LocalPlayer)
end
end
game:GetService("UserInputService").InputBegan:Connect(onKeyPress)