Menu
CoddyTech

Dorongan Mundur

Pelajaran 11 dari 25 dalam kursus Game Roblox: Battlegrounds di Coddy.

Bantingan harus melempar benda yang terkena. ApplyImpulse pada root mendorong seluruh tubuhnya. Impuls adalah perubahan kecepatan dikalikan massa, jadi mengalikan dengan AssemblyMass akan melempar rig ringan dan berat dengan cara yang sama:

theirRoot:ApplyImpulse((away * 30 + Vector3.new(0, 20, 0)) * theirRoot.AssemblyMass)

away mengarah dari kamu ke mereka, mendatar di tanah: posisi mereka dikurangi posisimu, dengan Y diatur menjadi nol, lalu .Unit untuk mendapatkan vektor dengan panjang 1.

challenge icon

Tantangan

Sedang

Buat Slam melempar semua orang yang terkena serangannya.

  1. Di abilities.Slam, setelah hurt: local away = (theirRoot.Position - root.Position) * Vector3.new(1, 0, 1), lalu away = away.Unit jika Magnitude-nya lebih dari 0.
  2. Lalu theirRoot:ApplyImpulse((away * Settings.SlamKnockback + Vector3.new(0, 40, 0)) * theirRoot.AssemblyMass).

Tekan tombol “Main”, berjalanlah di antara dua rig merah, lalu tekan E: keduanya akan terlempar menjauh. Lalu tekan tombol “Periksa”.

Coba sendiri

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

local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> waktu terakhir mengayunkan pedang

-- Animasi pedang bawaan Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"

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

-- Setiap serangan yang mengenai sasaran dalam game diproses di sini
local function hurt(humanoid, amount)
	if humanoid.Health <= 0 then
		return
	end
	local character = humanoid.Parent
	humanoid:TakeDamage(amount)
end

-- Ayunan pedang: animasi berjalan, lalu semua yang berada dalam kotak di depanmu terkena serangan
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()
	-- kotak di depanmu, bukan tubuhmu sendiri
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	local box = root.CFrame * CFrame.new(0, 0, -3)
	local hit = {} -- setiap humanoid hanya sekali per ayunan
	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
			hurt(humanoid, Settings.SwordDamage)
		end
	end
end

-- Kemampuan berdasarkan nama: fungsi masing-masing
local abilities = {}

-- perangkat pemain menggerakkan karakternya, jadi dash terjadi di sana
function abilities.Dash(player)
	remotes.Ability:FireClient(player, "Dash")
end

-- semua yang berada di sekitarmu terkena serangan
function abilities.Slam(player, character, root)
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	local hit = {}
	for _, part in workspace:GetPartBoundsInRadius(root.Position, Settings.SlamRadius, params) do
		local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
		local theirRoot = part.Parent:FindFirstChild("HumanoidRootPart")
		if humanoid and theirRoot and not hit[humanoid] then
			hit[humanoid] = true
			hurt(humanoid, Settings.SlamDamage)
			-- Pelajaran 11: Efek dorongan diterapkan di sini
		end
	end
end

-- Client meminta kemampuan berdasarkan nama. Server memeriksa apakah kemampuan itu valid,
-- pemainnya masih hidup, dan masa tunggunya selesai. Saat kemampuan itu siap digunakan lagi
-- adalah atribut pemain, sehingga layar mereka bisa menampilkannya.
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)

-- Setiap pemain mendapat pedang setiap kali hidup kembali
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)

-- Boneka latihan: bilah kesehatannya mengikuti kesehatannya, dan boneka yang dikalahkan
-- muncul kembali setelah beberapa saat sebagai salinan baru di tempat yang sama
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)

Semua pelajaran di Game Roblox: Battlegrounds

Latihan sendiri: Playground Roblox