Dash con Q
Lección 7 de 25 del curso Juego de Roblox: Batallas campales de Coddy.
Un impulso es un empujón: establecer AssemblyLinearVelocity de la raíz lanza al personaje. Pero Roblox permite que el dispositivo de cada jugador ejecute la física de su propio personaje, así que un empujón que establece el servidor apenas lo mueve. El servidor decide, y el propio LocalScript del jugador empuja.
El servidor mantiene sus habilidades en una tabla, por nombre, y una aprobación para un impulso vuelve al cliente de ese jugador con FireClient, donde se recibe mediante OnClientEvent:
remotes.Ability.OnClientEvent:Connect(function(name)
if name == "Hop" then
root.AssemblyLinearVelocity = Vector3.new(0, 50, 0)
end
end)Desafío
IntermedioHaz que Q realice un impulso: el servidor da el visto bueno y tu dispositivo te impulsa.
- En
BattleServer, sustituye la impresión por una tablaabilities:abilities.Dash(player)llama aremotes.Ability:FireClient(player, "Dash"). - El controlador ejecuta
abilities[name](player, character, root)si existe. - En
BattleClient, cuando se recibaremotes.Ability.OnClientEventcon"Dash", establece la velocidad de tu raíz enroot.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0).
Pulsa «Jugar» y pulsa Q: te impulsas hacia delante. Después, «Comprobar».
Pruébalo tú mismo
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> cuándo atacó por última vez
-- Las animaciones de espada propias de Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- Un espadazo: se reproduce la animación y luego se golpea a todos los que estén en el área frente a ti
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()
-- el área frente a ti, nunca tu propio cuerpo
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- cada humanoide solo una vez por espadazo
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)
print(humanoid.Parent.Name .. " is at " .. humanoid.Health)
end
end
end
-- El cliente solicita una habilidad por su nombre
remotes.Ability.OnServerEvent:Connect(function(player, name)
print(player.Name .. " asked for " .. name)
end)
-- Cada jugador recibe una espada en cada vida
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function()
local sword = ServerStorage.Sword:Clone()
sword.Parent = player.Backpack
sword.Activated:Connect(function()
swing(player)
end)
end)
end)
-- El muñeco de entrenamiento: su barra de salud refleja su salud y, cuando lo derrotan,
-- reaparece al cabo de un momento como una copia nueva en el mismo lugar
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)
Todas las lecciones de Juego de Roblox: Batallas campales
2Cliente y servidor
Pregunta al servidorPractica por tu cuenta: Playground de Roblox