Bodenschlag
Lektion 9 von 20 im Kurs Roblox-Spiel: Schlachtfelder von Coddy.
Eine zweite Fähigkeit auf E: ein Bodenschmettern, das alle um dich herum trifft und wegschleudert. workspace:GetPartBoundsInRadius(position, radius, params) findet die Teile innerhalb einer bestimmten Entfernung, und ApplyImpulse auf einem Root gibt dem ganzen Körper einen Schubs. Ein Impuls ist eine Geschwindigkeitsänderung multipliziert mit der Masse. Wenn du also mit AssemblyMass multiplizierst, werden leichte und schwere Rigs gleichermaßen weggeschleudert:
theirRoot:ApplyImpulse((away * Settings.SlamKnockback + Vector3.new(0, 40, 0)) * theirRoot.AssemblyMass)Jetzt hat das Spiel zwei Möglichkeiten, jemandem Schaden zuzufügen, und weitere kommen hinzu. Jeder Treffer läuft über eine Funktion, hurt(humanoid, amount), sodass eine Schadensregel (Blocken, nächste Lektion) nur einmal geschrieben wird.
Aufgabe
Mittel- Schreibe
hurt(humanoid, amount)oberhalb vonswing: Kehre zurück, wenn der Humanoid bereits besiegt ist, andernfallsTakeDamage(amount). Lassswingdie Funktion aufrufen. - Füge
abilities.Slamhinzu: Alle (jeweils einmal, nicht du selbst) mit einem Root innerhalb vonSettings.SlamRadiuserleiden durchhurtSettings.SlamDamageSchaden und werden mitSettings.SlamKnockbackund 40 nach oben von dir weggestoßen. - Binde in
BattleClient"Slam"an E und füge es der Abklingzeitanzeige hinzu.
Drücke Play und dann Check.
Probier es selbst
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> wann der Spieler zuletzt zugeschlagen hat
-- Roblox' eigene Schwertanimationen
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- Ein Schwerthieb: Erst läuft die Animation, dann werden alle in der Box vor dir getroffen
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()
-- die Box vor dir, niemals dein eigener Körper
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- jeder Humanoid nur einmal pro Schwerthieb
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
-- Die Fähigkeiten nach Namen: was jede davon bewirkt
local abilities = {}
function abilities.Dash(player, character, root)
root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end
-- Der Client fordert eine Fähigkeit anhand ihres Namens an. Der Server prüft: Ist es eine echte
-- Fähigkeit, lebt der Spieler und ist ihre Abklingzeit vorbei? Wann sie wieder bereit ist,
-- steht in einem Attribut des Spielers, damit es auf seinem Bildschirm angezeigt werden kann.
remotes.Ability.OnServerEvent:Connect(function(player, name)
if typeof(name) ~= "string" or not abilities[name] then
return
end
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or character.Humanoid.Health <= 0 then
return
end
local now = workspace:GetServerTimeNow()
if now < (player:GetAttribute(name .. "ReadyAt") or 0) then
return
end
player:SetAttribute(name .. "ReadyAt", now + Settings.Cooldowns[name])
abilities[name](player, character, root)
end)
-- Jeder Spieler erhält Kills auf der Bestenliste und bei jedem neuen Leben ein Schwert
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)
-- Die Trainingspuppe: Ihre Gesundheitsanzeige zeigt ihre Gesundheit an, und eine besiegte
-- Puppe erscheint kurz darauf als neue Kopie an derselben Stelle wieder
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)
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.