Anzeige der Abklingzeit
Lektion 8 von 20 im Kurs Roblox-Spiel: Schlachtfelder von Coddy.
Ein Spieler sollte sehen, wann eine Fähigkeit bereit ist. Das HUD hat einen Cooldowns-Frame mit einer Beschriftung pro Fähigkeit, und der Server speichert bereits DashReadyAt für den Spieler, wo dessen Client den Wert auslesen kann.
Ein Countdown ändert sich in jedem Frame, daher zeichnet der Client ihn bei RunService.Heartbeat neu, das einmal pro Frame ausgelöst wird. string.format behält eine Dezimalstelle bei:
string.format("%s %.1f", "Dash", 2.345) --> "Dash 2.3"Der Client zeigt nur die Abklingzeit an. Die Prüfung des Servers aus der letzten Lektion entscheidet weiterhin.
Aufgabe
MittelRufe in BattleClient RunService, local me = Players.LocalPlayer und local hud = script.Parent ab. Setze bei jedem Heartbeat für jeden Namen in local shown = { "Dash" } hud.Cooldowns[name].Text während der Abklingzeit auf Dash 2.3 und, sobald die Fähigkeit wieder bereit ist, auf Dash ready.
Drücke Play, drücke Q und beobachte die Beschriftung. Klicke dann auf 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 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 einzelne 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 gültige
-- Fähigkeit, lebt der Spieler und ist ihre Abklingzeit abgelaufen? Wann sie wieder verfügbar 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 bekommt Kills auf der Bestenliste und in jedem 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: Ihr Gesundheitsbalken zeigt ihre Gesundheit an, und eine besiegte
-- Puppe erscheint kurz darauf als neue Kopie am selben Ort
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.