Trong suốt các hướng dẫn Lập trình Cơ bản, bạn đã lập trình các phần riêng lẻ để tạo ra các cảnh có thể chơi được. Với phương pháp trước đó, nếu bạn sao chép các phần, bạn cũng sẽ có các kịch bản sao chép. Điều này sẽ làm cho việc cập nhật các kịch bản trở nên tẻ nhạt vì các thay đổi sẽ phải được thực hiện từng kịch bản một.
Trong hướng dẫn này, một mẫu khác sẽ được sử dụng để tạo ra một số vật phẩm hồi máu, với chỉ một bản sao của kịch bản xác định hành vi hồi máu. Khi vật phẩm được chạm vào, nó sẽ phục hồi sức khỏe của người chơi, mờ đi một chút và bị vô hiệu hóa trong một khoảng thời gian ngắn.
Thiết lập
Đầu tiên, bạn sẽ cần một phần hoặc một mô hình để sử dụng làm vật phẩm hồi máu. Thế giới ví dụ Showdown Town bao gồm nhiều vật phẩm hồi máu trải rộng khắp bản đồ.

Mỗi vật phẩm hồi máu là một Liên hợp của hai phần hình chữ nhật với một PointLight màu xanh lá cây bên trong. Tất cả chúng được lưu trữ trong một thư mục trong Workspace có tên là HealthPickups, nơi mà kịch bản sẽ tìm kiếm chúng. Nếu bạn thêm bất kỳ vật phẩm nào khác vào bản đồ, điều quan trọng là bạn phải đảm bảo rằng chúng cũng được lưu trữ trong thư mục này.


Khôi phục sức khỏe
Để bắt đầu, kịch bản cần khôi phục sức khỏe của người chơi. Mẫu này sẽ quen thuộc với bạn từ hướng dẫn Deadly Lava.
Trong ServerScriptService, thêm một kịch bản có tên là PickupManager.
Trong kịch bản này, khai báo một hằng số có tên MAX_HEALTH với giá trị 100.
Tạo một hàm có tên onTouchHealthPickup với các tham số cho phần khác đã chạm vào vật phẩm hồi máu và chính vật phẩm hồi máu.
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)endTrong hàm, lấy mô hình nhân vật từ cha của otherPart. Tiếp theo, kiểm tra xem nó có Humanoid bằng cách sử dụng FindFirstChildWhichIsA().
Nếu nó có một humanoid, đặt thuộc tính Health của họ thành MAX_HEALTH.
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)local character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendend
Lấy thư mục vật phẩm hồi máu
Thư mục chứa các vật phẩm hồi máu có thể chưa được tải vào trò chơi vào thời điểm kịch bản chạy. WaitForChild có thể được sử dụng để tạm dừng kịch bản và lấy thư mục HealthPickups khi nó được tải.
Khi được gọi trên một thư mục, hàm GetChildren sẽ trả về một mảng các nội dung của thư mục.
Dưới MAX_HEALTH, khai báo một biến có tên healthPickupsFolder và sử dụng hàm WaitForChild để lấy thư mục HealthPickups từ Workspace.
Tạo một biến có tên healthPickups để lưu trữ kết quả của việc gọi hàm GetChildren trên healthPickupsFolder.
local MAX_HEALTH = 100local healthPickupsFolder = workspace:WaitForChild("HealthPickups")local healthPickups = healthPickupsFolder:GetChildren()local function onTouchHealthPickup(otherPart, healthPickup)local character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendend
Vòng lặp với ipairs
onTouchHealthPickup cần được gọi cho mỗi vật phẩm hồi máu trong mảng. Để làm điều này một cách hiệu quả, một loại cú pháp vòng lặp mới sẽ được sử dụng.
ipairs là một hàm có thể được sử dụng với vòng lặp for để đi qua từng phần tử của một mảng. Bạn không cần phải chỉ định nơi vòng lặp bắt đầu và kết thúc. Một vòng lặp for sử dụng ipairs được định nghĩa như sau:

- Chỉ số: điều này tương đương với biến điều khiển trong một vòng lặp for thông thường.
- Giá trị: điều này sẽ được điền với mỗi phần tử trong mảng khi vòng lặp lặp lại. Thật tốt khi đặt tên biến giá trị theo những gì nó thực sự sẽ chứa.
- Mảng: mảng bạn muốn lặp qua được truyền vào hàm ipairs.
Trong mã sau, bạn không cần chỉ số cho bất cứ điều gì, vì vậy nó có thể được để trống với _. Tạo một vòng lặp for sử dụng hàm ipairs, truyền vào healthPickups.
local function onTouchHealthPickup(otherPart, healthPickup)
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = MAX_HEALTH
end
end
for _, healthPickup in ipairs(healthPickups) do
endMột hàm bọc sẽ cần thiết để truyền vật phẩm hồi máu vào hàm onTouchHealthPickup khi kết nối với sự kiện Touched.
Trong vòng lặp for, kết nối sự kiện Touched với một hàm ẩn danh có tham số gọi là otherPart.
Gọi hàm onTouchHealthPickups, truyền cả tham số otherPart và healthPickup.
for _, healthPickup in ipairs(healthPickups) dohealthPickup.Touched:Connect(function(otherPart)onTouchHealthPickup(otherPart, healthPickup)end)end
Kiểm tra mã của bạn bây giờ và bạn sẽ thấy rằng vật phẩm hồi máu phục hồi sức khỏe của bạn. Bạn sẽ cần làm tổn thương người chơi của mình trước - hãy thử đứng trên lỗ thông gió bên cạnh điểm xuất phát.

Một thanh sức khỏe sẽ xuất hiện ở góc trên bên phải và sẽ biến mất khi người chơi được hồi phục.
Thời gian hồi của vật phẩm
Hiện tại, vật phẩm sẽ hồi phục vô hạn cho bất kỳ người chơi nào chạm vào nó. Sẽ hiệu quả hơn nếu nó chỉ có thể được nhặt một lần, với một khoảng thời gian hồi ngắn trước khi có thể được sử dụng lại.
Đầu tiên, bạn cần ghi lại xem vật phẩm có đang trong thời gian hồi hay không. Mẫu dưới đây sẽ quen thuộc với bạn từ Fade Trap - lần này, việc chống lại sẽ được thực hiện bằng cách đặt một thuộc tính trên vật phẩm hồi máu.
Trong vòng lặp for, đặt một thuộc tính mới có tên là "Enabled" thành true.
Bọc mã bên trong onTouchHealthPickup trong một câu lệnh if với điều kiện healthPickup:GetAttribute("Enabled").
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendendendfor _, healthPickup in ipairs(healthPickups) dohealthPickup:SetAttribute("Enabled", true)healthPickup.Touched:Connect(function(otherPart)onTouchHealthPickup(otherPart, healthPickup)end)end
Vô hiệu hóa vật phẩm
Vật phẩm nên cung cấp phản hồi hình ảnh rằng nó đã bị vô hiệu hóa - một cách phổ biến để chỉ ra điều này là làm cho nó hơi trong suốt.
Khai báo ba hằng số ở đầu kịch bản (cảm thấy tự do điều chỉnh mỗi giá trị theo sở thích của bạn):
- ENABLED_TRANSPARENCY = 0.4
- DISABLED_TRANSPARENCY = 0.9
- COOLDOWN = 10
local MAX_HEALTH = 100local ENABLED_TRANSPARENCY = 0.4local DISABLED_TRANSPARENCY = 0.9local COOLDOWN = 10local healthPickupsFolder = workspace:WaitForChild("HealthPickups")Trong câu lệnh if trong onTouchHealthPickup, đặt Transparency của vật phẩm thành DISABLED_TRANSPARENCY, và giá trị của thuộc tính Enabled thành false.
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHhealthPickup.Transparency = DISABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", false)endendendGọi hàm task.wait(), truyền COOLDOWN làm thời gian chờ.
Đặt Transparency trở lại ENABLED_TRANSPARENCY và Enabled trở lại true.
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHhealthPickup.Transparency = DISABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", false)task.wait(COOLDOWN)healthPickup.Transparency = ENABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", true)endendend
Kiểm tra vật phẩm của bạn một lần nữa: bạn sẽ thấy rằng khi bạn chạm vào vật phẩm, nó phục hồi sức khỏe của bạn, trở nên trong suốt, rồi trở lại sẵn sàng để sử dụng lại.
Nếu bạn muốn làm cho phản hồi trở nên ấn tượng hơn cho người chơi khi vật phẩm được thu thập, hãy thử giảm độ sáng của PointLight trong vật phẩm khi bạn thay đổi độ trong suốt.
Hãy thử sử dụng những vật phẩm hồi máu này trong các dự án của riêng bạn, hoặc thay đổi hình thức và hiệu ứng để cung cấp một loại tăng cường khác cho người chơi của bạn.
Mã cuối cùng
local MAX_HEALTH = 100
local ENABLED_TRANSPARENCY = 0.4
local DISABLED_TRANSPARENCY = 0.9
local COOLDOWN = 10
local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
local healthPickups = healthPickupsFolder:GetChildren()
local function onTouchHealthPickup(otherPart, healthPickup)
if healthPickup:GetAttribute("Enabled") then
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = MAX_HEALTH
healthPickup.Transparency = DISABLED_TRANSPARENCY
healthPickup:SetAttribute("Enabled", false)
task.wait(COOLDOWN)
healthPickup.Transparency = ENABLED_TRANSPARENCY
healthPickup:SetAttribute("Enabled", true)
end
end
end
for _, healthPickup in ipairs(healthPickups) do
healthPickup:SetAttribute("Enabled", true)
healthPickup.Touched:Connect(function(otherPart)
onTouchHealthPickup(otherPart, healthPickup)
end)
end