iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0

打開應用單元的專案吧,我們來做最後的收尾


1. 系統化所有的程式

我們昨天學過了標籤系統,現在我們要將這項系統應用在遊戲裡面,我們的最終目標是讓整個遊戲只有一個腳本在控制,所以我們先來處理死亡方塊。

首先,在ServerScriptService裡面新增一個Script,然後為所有的死亡方塊加上標籤。
https://ithelp.ithome.com.tw/upload/images/20250910/20169664KVa2dfXP4s.png
我把腳本名稱改為MainScript

https://ithelp.ithome.com.tw/upload/images/20250910/20169664pLB8KnPcaA.png
然後標籤名為KillerPart

接著我們要在遊戲開始的時候透過一項for迴圈去遍歷所有帶有此標籤的物件

--ServerScriptService.MainScript
for _, Part in pairs(workspace:GetChildren()) do
    if Part:IsA("BasePart") and Part:HasTag("KillerPart") then

    end
end

現在我們過濾出了死亡方塊,接著就可以把死亡方塊的腳本內的指令直接導進這邊

--ServerScriptService.MainScript
function OnTouch(Hit) --之前寫過的函式直接貼到這邊
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	if Player then
		Player.Character:WaitForChild("Humanoid").Health = 0
	end
end


for _, Part in pairs(workspace:GetChildren()) do
    if Part:IsA("BasePart") and Part:HasTag("KillerPart") then
        Part.Touched:Connect(OnTouch) --連接
    end
end

然後把所有死亡方塊內的腳本全部刪掉

接著以同樣的方法為消失方塊做系統化

--ServerScriptService.MainScript
function OnTouch(Hit)
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	if Player then
		Player.Character:WaitForChild("Humanoid").Health = 0
	end
end

for _, Part in pairs(workspace:GetDescendants()) do
	if Part:HasTag("KillerPart") then
		Part.Touched:Connect(OnTouch)
	end
	if Part:HasTag("DisappearPart") then
		Part.Touched:Connect(function(Hit) --由於我們要取得呼叫此函式的物件,所以要以這樣的方式連接函式,否則須以更複雜的方式定義
			local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
			if Player then
				task.wait(0.5)
				Part.Transparency = 1
				Part.CanCollide = false
				task.wait(0.5)
				Part.Transparency = 0
				Part.CanCollide = true
			end
		end)
	end
end

然後,我們也可以把消失方塊的程式改成以動畫的方式消失,透過第24天講到的TweenService

--ServerScriptService.MainScript
function OnTouchKill(Hit)
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	if Player then
		Player.Character:WaitForChild("Humanoid").Health = 0
	end
end

for _, Part in pairs(workspace:GetDescendants()) do
	if Part:HasTag("KillerPart") then
		Part.Touched:Connect(OnTouchKill)
	end
	if Part:HasTag("DisappearPart") then
		Part.Touched:Connect(function(Hit)
			local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
			if Player then
				task.wait(0.25) --改一下等待時間
				game:GetService("TweenService"):Create(Part, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {["Transparency"] = 1}):Play()
				Part.CanCollide = false
				task.wait(2)
				game:GetService("TweenService"):Create(Part, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {["Transparency"] = 0}):Play()
				Part.CanCollide = true
			end
		end)
	end
end

2. 一些很酷的動畫

剛提到了TweenService,那不如我們也把密碼門套上動畫吧!

--CodeDoor.Script
local Delete = script.Parent:WaitForChild("Delete")
local Enter = script.Parent:WaitForChild("Enter")
local Output = script.Parent:WaitForChild("Output")
local Door = script.Parent:WaitForChild("Door")

local FinalCode = "5312"
local InputCode = ""

for index, Button in pairs(script.Parent:GetChildren()) do
	if Button:FindFirstChild("ClickDetector") then
		if Button.Name == "Delete" then 
			Button:WaitForChild("ClickDetector").MouseClick:Connect(function(Player)
				InputCode = ""
				Output.SurfaceGui.TextLabel.Text = ""
			end)
			continue
		end 
		if Button.Name == "Enter" then 
			Button:WaitForChild("ClickDetector").MouseClick:Connect(function(Player)
				if InputCode == FinalCode then
					print("密碼正確")
					Door.CanCollide = false
					game:GetService("TweenService"):Create(Door, TweenInfo.new(1, Enum.EasingStyle.Linear), {["Transparency"] = 1}):Play() --消失
					task.wait(2)
					Door.CanCollide = true
					game:GetService("TweenService"):Create(Door, TweenInfo.new(1, Enum.EasingStyle.Linear), {["Transparency"] = 0}):Play() --出現
				else
					print("密碼錯誤")
				end
				InputCode = ""
				Output.SurfaceGui.TextLabel.Text = ""
			end)
			continue
		end
		Button:WaitForChild("ClickDetector").MouseClick:Connect(function(Player)
			InputCode = InputCode..Button.Name
			Output.SurfaceGui.TextLabel.Text = InputCode
		end)
	end
end

3. 安全措施

然後上一次的迷宮好像太小了,玩家可以直接跳出去,所以在這邊我們要在玩家進入迷宮後把玩家的跳躍力改成0
https://ithelp.ithome.com.tw/upload/images/20250910/20169664kh9lazrJ0s.png

--ServerScriptService.MainScript
--以上略

workspace.CodeDoor:WaitForChild("Door").Touched:Connect(function(Hit)
	local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
	if Player and workspace.CodeDoor:WaitForChild("Door").CanCollide == false then
		Player.Character.Humanoid.JumpPower = 0
	end
end)

然後運行之前記得要把StarterPlayer裡的CharacterUseJumpPower的值改為true
https://ithelp.ithome.com.tw/upload/images/20250910/20169664boFYJ8yeAW.png

但玩家還是可以直接用跳的進入迷宮,甚至不用打密碼,所以我們要在門的上方放一塊隱形牆 (就是Transparency = 0的Part,這個非常的簡單我就不放圖了)

然後我們要在玩家找到按鈕後恢復他的跳躍力

--workspace.button.Script
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")

ClickDetector.MouseClick:Connect(function(Player)
	Player.Character:WaitForChild("HumanoidRootPart").CFrame = workspace:WaitForChild("PlayerPosition").CFrame
	Player.Character.Humanoid.JumpPower = 50 --把跳躍力改回來
end)

4. 通關畫面

最後,我們要在玩家通過前面三個關卡後,給予玩家一個恭喜的畫面,使用SurfaceGui
https://ithelp.ithome.com.tw/upload/images/20250910/20169664bfWdVWxOJv.png


感謝大家把這一個月的文章看到這邊,這是我第一次參加這種比賽,說真的非常的累,光是每天要想要教什麼、怎麼教、放什麼才會比較好懂,都快讓我顛顯發作 (開玩笑),總之,非常謝謝大家一路以來的支持,這一次的賽事所使用的應用單元檔案在這邊,如果不嫌棄的話可以載下來玩玩看

氣貫長虹!!
--Grosstofu 2025/9/10


上一篇
Day 29: Tags標籤系統
系列文
透過Roblox Studio學習Lua語言與基本程式邏輯30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言