ตลอดการสอนการเขียนสคริปต์พื้นฐาน คุณได้เขียนสคริปต์สำหรับชิ้นส่วนแต่ละชิ้นเพื่อสร้างฉากที่เล่นได้ ด้วยวิธีการก่อนหน้านี้ หากคุณทำการคัดลอกชิ้นส่วน คุณก็จะมีสคริปต์ที่ซ้ำกันด้วย ซึ่งจะทำให้การอัปเดตสคริปต์เป็นเรื่องที่น่าเบื่อหน่าย เนื่องจากการเปลี่ยนแปลงจะต้องทำทีละสคริปต์
ในบทเรียนนี้ จะใช้รูปแบบที่แตกต่างกันในการสร้างการเก็บสุขภาพจำนวนมาก โดยมีสคริปต์เพียงชุดเดียวที่กำหนดพฤติกรรมการเก็บสุขภาพ เมื่อมีการสัมผัสการเก็บ มันจะฟื้นฟูสุขภาพของผู้เล่น ทำให้จางลงเล็กน้อย และถูกปิดใช้งานเป็นระยะเวลาสั้น ๆ
ตั้งค่า
ก่อนอื่น คุณจะต้องมีชิ้นส่วนหรือโมเดลเพื่อใช้เป็นการเก็บสุขภาพ ตัวอย่างโลก Showdown Town มีการเก็บสุขภาพมากมายกระจายอยู่ทั่วแผนที่

การเก็บสุขภาพแต่ละชิ้นเป็นการรวมกันของชิ้นส่วนสี่เหลี่ยมผืนผ้าสองชิ้นที่มี PointLight สีเขียวอยู่ภายใน พวกมันทั้งหมดถูกเก็บไว้ในโฟลเดอร์เดียวใน Workspace ที่เรียกว่า HealthPickups ซึ่งเป็นที่ที่สคริปต์จะมองหาพวกมัน หากคุณเพิ่มอะไรเพิ่มเติมลงในแผนที่ สิ่งสำคัญคือคุณต้องมั่นใจว่าพวกมันถูกเก็บไว้ในโฟลเดอร์นี้ด้วย


ฟื้นฟูสุขภาพ
เริ่มต้นด้วย สคริปต์ต้องฟื้นฟูสุขภาพของผู้เล่น รูปแบบนี้ควรจะคุ้นเคยกับคุณจากบทเรียน Deadly Lava
ใน ServerScriptService ให้เพิ่มสคริปต์ที่เรียกว่า PickupManager
ในสคริปต์นี้ ให้ประกาศค่าคงที่ที่เรียกว่า MAX_HEALTH โดยมีค่าเป็น 100
สร้างฟังก์ชันที่เรียกว่า onTouchHealthPickup โดยมีพารามิเตอร์สำหรับชิ้นส่วนอื่นที่สัมผัสการเก็บและการเก็บสุขภาพเอง
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)endในฟังก์ชัน ให้ดึงโมเดลตัวละครจากพ่อแม่ของ otherPart จากนั้นตรวจสอบว่ามี Humanoid โดยใช้ FindFirstChildWhichIsA()
หากมี humanoid ให้ตั้งค่า Health ของพวกเขาเป็น MAX_HEALTH
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)local character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendend
รับโฟลเดอร์การเก็บ
โฟลเดอร์ที่เก็บการเก็บสุขภาพอาจยังไม่โหลดเข้าสู่เกมเมื่อสคริปต์ทำงาน WaitForChild สามารถใช้เพื่อหยุดสคริปต์และรับโฟลเดอร์ HealthPickups เมื่อมันโหลด
เมื่อเรียกใช้บนโฟลเดอร์ ฟังก์ชัน GetChildren จะคืนค่าอาร์เรย์ของเนื้อหาของโฟลเดอร์
ใต้ MAX_HEALTH ให้ประกาศตัวแปรที่เรียกว่า healthPickupsFolder และใช้ฟังก์ชัน WaitForChild เพื่อรับโฟลเดอร์ HealthPickups จาก Workspace
สร้างตัวแปรชื่อ healthPickups เพื่อเก็บผลลัพธ์จากการเรียกใช้ฟังก์ชัน GetChildren บน 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
ลูปด้วย ipairs
onTouchHealthPickup ต้องถูกเรียกสำหรับการเก็บสุขภาพแต่ละชิ้นในอาร์เรย์ เพื่อทำเช่นนี้อย่างมีประสิทธิภาพ จะใช้ไวยากรณ์ลูปชนิดใหม่
ipairs เป็นฟังก์ชันที่สามารถใช้กับลูป for เพื่อผ่านแต่ละองค์ประกอบของอาร์เรย์ คุณไม่จำเป็นต้องระบุว่าลูปเริ่มต้นและสิ้นสุดที่ไหน ลูป for ที่ใช้ ipairs ถูกกำหนดดังนี้:

- Index: นี่เทียบเท่ากับตัวแปรควบคุมในลูป for ปกติ
- Value: นี่จะถูกเติมเต็มด้วยแต่ละองค์ประกอบในอาร์เรย์เมื่อมีการวนลูป เป็นความคิดที่ดีที่จะตั้งชื่อตัวแปร value ตามสิ่งที่มันจะเก็บจริง ๆ
- Array: อาร์เรย์ที่คุณต้องการวนซ้ำจะถูกส่งไปยังฟังก์ชัน ipairs
ในโค้ดต่อไปนี้ คุณไม่จำเป็นต้องใช้ดัชนีสำหรับอะไร ดังนั้นมันสามารถถูกทิ้งว่างไว้ด้วย _ สร้างลูป for โดยใช้ฟังก์ชัน ipairs โดยส่ง 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
endจะต้องมีฟังก์ชันห่อหุ้มเพื่อส่งการเก็บสุขภาพไปยังฟังก์ชัน onTouchHealthPickup เมื่อเชื่อมต่อกับเหตุการณ์ Touched
ในลูป for เชื่อมต่อเหตุการณ์ Touched กับฟังก์ชันนิรนามที่มีพารามิเตอร์ชื่อ otherPart
เรียกใช้ฟังก์ชัน onTouchHealthPickups โดยส่งพารามิเตอร์ otherPart และ healthPickup
for _, healthPickup in ipairs(healthPickups) dohealthPickup.Touched:Connect(function(otherPart)onTouchHealthPickup(otherPart, healthPickup)end)end
ทดสอบโค้ดของคุณตอนนี้และคุณควรพบว่าการเก็บสุขภาพฟื้นฟูสุขภาพของคุณ คุณจะต้องทำให้ผู้เล่นของคุณได้รับความเสียหายก่อน - ลองยืนอยู่บนช่องระบายอากาศข้างจุดเกิด

แถบสุขภาพควรปรากฏขึ้นที่มุมขวาบนซึ่งจะหายไปเมื่อผู้เล่นได้รับการรักษา
การตั้งเวลาเก็บ
ขณะนี้ การเก็บจะฟื้นฟูผู้เล่นที่สัมผัสมันได้ไม่จำกัด จะมีประสิทธิภาพมากขึ้นหากมันสามารถเก็บได้เพียงครั้งเดียว โดยมีการตั้งเวลาสั้น ๆ ก่อนที่จะสามารถใช้งานได้อีกครั้ง
ก่อนอื่น คุณต้องบันทึกว่าการเก็บอยู่ในช่วงเวลาตั้งเวลาหรือไม่ รูปแบบด้านล่างควรคุ้นเคยจาก Fade Trap - ในครั้งนี้ การตั้งเวลาจะทำได้โดยการตั้งค่าคุณสมบัติในการเก็บสุขภาพ
ในลูป for ตั้งค่าคุณสมบัติใหม่ที่เรียกว่า "Enabled" เป็น true
ห่อหุ้มโค้ดภายใน onTouchHealthPickup ในคำสั่ง if โดยมีเงื่อนไขว่า 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
ปิดการเก็บ
การเก็บควรให้ข้อเสนอแนะแบบภาพว่ามันถูกปิดใช้งาน - วิธีทั่วไปในการระบุสิ่งนี้คือการทำให้มันโปร่งใสเล็กน้อย
ประกาศค่าคงที่สามค่าที่ด้านบนของสคริปต์ (คุณสามารถปรับค่าทุกค่าให้ตรงตามที่คุณต้องการ):
- 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")ในคำสั่ง if ใน onTouchHealthPickup ให้ตั้งค่า Transparency ของการเก็บเป็น DISABLED_TRANSPARENCY และค่าของคุณสมบัติ Enabled เป็น 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)endendendเรียกใช้ฟังก์ชัน task.wait() โดยส่ง COOLDOWN เป็นจำนวนเวลาที่จะรอ
ตั้งค่า Transparency กลับไปที่ ENABLED_TRANSPARENCY และ Enabled กลับไปที่ 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
ทดสอบการเก็บของคุณอีกครั้ง: คุณควรพบว่าหากคุณสัมผัสการเก็บ มันจะฟื้นฟูสุขภาพของคุณ ทำให้โปร่งใส จากนั้นกลับมาใช้งานได้อีกครั้ง
หากคุณต้องการทำให้ข้อเสนอแนะแบบภาพมีผลกระทบมากขึ้นสำหรับผู้เล่นเมื่อเก็บถูกเก็บ ลองลดความสว่างของ PointLight ในการเก็บเมื่อคุณเปลี่ยนความโปร่งใส
ลองใช้การเก็บสุขภาพเหล่านี้ในโปรเจกต์ของคุณเอง หรือเปลี่ยนรูปลักษณ์และผลกระทบเพื่อให้พลังอัพที่แตกต่างกันแก่ผู้เล่นของคุณ
โค้ดสุดท้าย
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