Menu
CoddyTech

Dash on Q

Lesson 6 of 20 in Coddy's Roblox Game: Battlegrounds course.

Abilities start on the player's device. BattleClient is a LocalScript in the HUD, and ContextActionService ties an action to keys, and with a true third argument also makes a button for it on a phone screen:

ContextActionService:BindAction("Dash", use, true, Enum.KeyCode.Q)

The function gets the action's name and the input's state, Begin when the key goes down. The server owns the game's rules, so the client does not dash on its own: it asks the server through the RemoteEvent Remotes.Ability, by name. The server keeps a table of abilities by name, and a dash is a push: setting the root's velocity throws the character forward.

function abilities.Dash(player, character, root)
	root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end
challenge icon

Challenge

Medium

In BattleClient: get ContextActionService and the Remotes folder, write use(name, state) that fires remotes.Ability with the name on Begin, and bind "Dash" to Q with a touch button.

In BattleServer: add local remotes = game.ReplicatedStorage.Remotes, an abilities table with Dash, and connect remotes.Ability.OnServerEvent(player, name) to run the named ability with the player, their character and its root.

Press Play and press Q. Then Check.

Try it yourself

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local lastSwing = {} -- player -> when they last swung

-- Roblox's own sword animations
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"

print("Swords deal " .. Settings.SwordDamage .. " damage")

-- A swing: the animation, then everyone in the box in front of you is hit
local function swing(player)
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or character.Humanoid.Health <= 0 then
		return
	end
	local now = time()
	if lastSwing[player] and now - lastSwing[player] < Settings.SwingCooldown then
		return
	end
	lastSwing[player] = now
	character.Humanoid.Animator:LoadAnimation(slash):Play()
	-- the box in front of you, never your own body
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	local box = root.CFrame * CFrame.new(0, 0, -3)
	local hit = {} -- each humanoid once per swing
	for _, part in workspace:GetPartBoundsInBox(box, Settings.HitboxSize, params) do
		local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
		if humanoid and not hit[humanoid] then
			hit[humanoid] = true
			humanoid:TakeDamage(Settings.SwordDamage)
		end
	end
end

-- Every player gets Kills on the leaderboard, and a sword every life
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local kills = Instance.new("IntValue")
	kills.Name = "Kills"
	kills.Parent = leaderstats

	player.CharacterAdded:Connect(function()
		local sword = ServerStorage.Sword:Clone()
		sword.Parent = player.Backpack
		sword.Activated:Connect(function()
			swing(player)
		end)
	end)
end)

-- The training dummy: its health bar follows its health, and a beaten
-- dummy comes back after a moment, a fresh copy in the same place
local function setupDummy(dummy)
	local humanoid = dummy.Humanoid
	humanoid.HealthChanged:Connect(function(health)
		dummy.HealthBar.Back.Fill.Size = UDim2.fromScale(health / humanoid.MaxHealth, 1)
	end)
	humanoid.Died:Connect(function()
		local spot = dummy:GetPivot()
		task.wait(0.5)
		dummy:Destroy()
		task.wait(Settings.DummyRespawn)
		local fresh = ServerStorage.Dummy:Clone()
		fresh:PivotTo(spot)
		fresh.Parent = workspace
		setupDummy(fresh)
	end)
end
setupDummy(workspace.Dummy)
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Roblox Game: Battlegrounds