你有乖乖聽話沒把上次應用單元的檔案丟掉吧?
今天我們要為上一次做跑酷遊戲增添兩項關卡,分別為密碼門與找按鈕。
好的我們先把概念理清楚,我們要做一個可以讓玩家透過按下不同物件來輸入密碼的數字鍵,並且要在玩家輸入了指定密碼後將門的CanCollide設為false以及將Transparency設為1,並且在某處藏一個按鈕,當玩家按下按鈕後在玩家的畫面顯示一項UI,該UI會顯示當前密碼為何。
好的現在可以開始製作了,首先打開上次的專案
接著建構密碼門關卡的各項模型,這裡你可以自由發揮創意
場景建置完成後,接著我們要來製作密碼門的模型,這裡我就以最簡單的方式來製作
接著我們來做各項物件的新增,首先是各個按鈕的文字,這邊要使用一項叫做SurfaceGui的物件,他跟ScreenGui類似,不過顯示的表面是物件的某一面,至於這個表面的位置可以在屬性頁面的Face屬性作更動,如果你看不到你放的UI那通常就是這個屬性把UI顯示到其他面了。
接下來SurfaceGui裡面的物件就跟ScreenGui的方法一樣,我就不細講了。總之新增好以後,我們要將所有按鈕物件新增一個ClickDetector,然後將密碼門的所有要素 (門、按鈕、輸出顯示)整理到一個Folder裡面,你可以把他們選取起來再按右鍵選擇組合成資料夾
然後各項物件的名稱也要做更改,這樣才可以避免等等在腳本中無法定義
接下來,在Folder中新增一個Script (不可以是Local的),並完成以下定義
local Buttons = {}
local Delete = script.Parent:WaitForChild("Delete")
local Enter = script.Parent:WaitForChild("Enter")
local Output = script.Parent:WaitForChild("Output")
local Door = script.Parent:WaitForChild("Door")
在這邊我不會選擇把所有的數字按鈕定義出來,因為這樣太耗時間了,而且在後續的函式連接也會很麻煩,我採用的是透過for迴圈來取得所有按鈕,再透過過濾來取得所有數字按鈕。
接著定義出for迴圈與最終密碼
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" --這個是最終密碼
for index, Button in pairs(script.Parent:GetChildren()) do
if Button:FindFirstChild("ClickDetector") then
if Button.Name == "Delete" then
--這邊是過濾出來的按鈕,也就是刪除鍵
continue --避免迴圈繼續進行,而導致這兩個按鍵也被視為可輸入的數字鍵
end
if Button.Name == "Enter" then
--而這邊則是確認鍵
continue
end
--這邊是過濾過後的按鈕,也就是數字按鈕
end
end
接下來,我們還要定義出一個字串變數,這項變數會儲存玩家的輸入
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
continue
end
if Button.Name == "Enter" then
continue
end
end
end
當然,你可以直接把Output物件顯示的字當成儲存玩家輸入的變數,但為了嚴謹一點,我還是會在腳本裡多定義一個變數
現在,我們先來做一般數字鍵的按下事件與連接函式
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
continue
end
if Button.Name == "Enter" then
continue
end
Button:WaitForChild("ClickDetector").MouseClick:Connect(function(Player) --這個你熟
InputCode = InputCode..Button.Name --將玩家的輸入儲存到變數,輸入的值就是這項物件的名稱
Output.SurfaceGui.TextLabel.Text = InputCode --接著把變數值更新到物件上
end)
end
end
然後來做刪除鍵
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
continue
end
Button:WaitForChild("ClickDetector").MouseClick:Connect(function(Player)
InputCode = InputCode..Button.Name
Output.SurfaceGui.TextLabel.Text = InputCode
end)
end
end
最後是確認鍵
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
Door.Transparency = 1
task.wait(2) --等個兩秒在回復
Door.CanCollide = true
Door.Transparency = 0
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
接著進入遊戲看看是否正確執行
接下來,我們要製作一個小提示按鈕。照慣例,先把按鈕的模型跟位置放好
然後看你想用哪種觸發方式,反正忘記了可以看昨天的單元,這邊我就一樣用CLickDetector
嘿對然後腳本一樣要新增
各項定義還有函式連接先做好
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")
ClickDetector.MouseClick:Connect(function(Player)
end)
接著,取得玩家的PlayerGui
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")
ClickDetector.MouseClick:Connect(function(Player)
local PlayerGui = Player.PlayerGui
end)
然後關閉腳本,我們來製作UI
這部分你就自己發揮,我就先做一個簡單的
回到腳本,把我們剛剛新增的UI顯示,然後等待一秒後再隱藏
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")
ClickDetector.MouseClick:Connect(function(Player)
local PlayerGui = Player.PlayerGui
PlayerGui.ScreenGui:WaitForChild("TextLabel").Visible = true
task.wait(1)
PlayerGui.ScreenGui:WaitForChild("TextLabel").Visible = false
end)
這部分我想要用一個迷宮,讓玩家在迷宮裡找按鈕,玩家找到按鈕後再把玩家傳送到下一關卡的位置
首先先做一個迷宮,你懶的話可以直接用ToolBox的
然後放按鈕
接下來進入腳本,然後一樣定義跟事件連接
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")
ClickDetector.MouseClick:Connect(function(Player)
end)
但現在,我們要傳送玩家,回到地點,接著新增一個Part來代表玩家的位置 (記得關碰撞跟隱藏)
然後在腳本裡新增傳送的指令
local Part = script.Parent
local ClickDetector = Part:WaitForChild("ClickDetector")
ClickDetector.MouseClick:Connect(function(Player)
--說是傳送,其實就只是改變CFrame而已
Player.Character:WaitForChild("HumanoidRootPart").CFrame = workspace:WaitForChild("PlayerPosition").CFrame
end)
進入遊戲測試
拜託不要把這個檔案刪掉欸