新增回合

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

添加回合 讓您將遊戲結構成階段,有明確的開始和結束點,以便玩家可以測量進度並有定期的平等遊戲場地機會。這對團隊基礎的遊戲特別重要,因為它為玩家提供轉換他們在那一回合中屬於誰的遊戲風格的機會。

使用 樣本雷射標籤體驗 作為參考,本教學的這一部分教你如何使用和自定義 Roblox 內置功能來結構每一回合,包括關於腳本指引的指示:

  • 通過重置個人和團隊點數開始回合,然後生成玩家到他們的團隊生成區。
  • 自訂變量,設置每位玩家螢幕頂部的回合目標。
  • 追蹤玩家點數貢獻以獲得團隊得分。
  • 根據玩家的團隊是否贏得或輸掉回合來啟動獨特的使用者介面屏幕。
  • 通過切斷玩家並將他們重生到中立大廳來結束一回合。

完成這一部分後,您將學習如何實現準確且令玩家滿意的爆破行為。

開始循環

伺服器腳本服務 > 遊戲 > 回合 處理了回合的大部分邏輯,並且由呼叫 startRoundLoopAsync() 函數開始,標記回合循環的開始。當玩家加入大廳並等待排團隊時,startRoundLoopAsync() 呼叫 resetScores() 函數在 ServerScriptService > 遊戲 > 評分 來重置排行榜和隊伍點數。

評分

function Scoring.resetScores()
for _, player in Players:GetPlayers() do
player.leaderstats.Points.Value = 0
end
for _, team in Teams:GetTeams() do
team:SetAttribute(GuiAttribute.teamPoints, 0)
end
end

現在每個人都從零點開始, 然後將中立生成地點置的屬性設為假,以便只有擁有與生成地點置相同屬性的玩家才能在那裡生成。因為生成地點置的 TeamColor 屬性已設為 白色 而不是樣本的薄荷或玫瑰粉紅色隊伍,這種配置會防止所有玩家在回合活動期間在那裡重生或重生。

對於目前在大廳的玩家,startRoundLoopAsync() 將所有現在在體驗中的玩家傳送到spawnPlayersInMap 功能中的 服務器腳本服務 > 遊戲 > 回合 > 在地圖上生成玩家 以排序並平衡每個人的隊伍約有相同數量的玩家。

對於在大廳群組被排序為團隊後加入體驗的任何新玩家,startRoundLoopAsync() 聆聽 Players.PlayerAdded:Connect 事件,然後再次呼叫 spawnPlayersInMap 函數將他們加入團隊,與最少數玩家一起。有關此過程的更多信息,請參閱配置重生位置從教學的以前的 重生和重生 部分。

回合

-- 在地圖上生成所有玩家
neutralSpawn.Neutral = false
spawnPlayersInMap(Players:GetPlayers())
-- 當新玩家加入時,在地圖上生成新玩家
local playerAddedConnection = Players.PlayerAdded:Connect(function(player: Player)
spawnPlayersInMap({ player })
end)

設定目標

現在每位玩家都在競技場與隊友一起,體驗需要提供在回合內成功的指示。樣本雷射標籤體驗以提供每位玩家畫面頂部的客觀提示來滿足這個需求,並提供清晰的指示,告知團隊需要做什麼才能獲勝。

雖然您可以在 UI 課程中了解更多關於如何配置和顯示 目標用戶介面 組件的方法,本部分專注於如何在回合開始時實現目標目標,從如何設置每個團隊需要完成回合的點數開始。

即使在運行時目標提示通知玩家他們需要得分三分才能獲勝,如果您在 StarterGui > HUDGui 中查看提示,您可以看到它實際上包含可配置的""點值。

「 」是一個可以隨時增加或減少的暫時字串,可以通過在 ReplicatedStorage > TEAM_SCORE_LIMIT 變量中更新來滿足自己的遊戲需求。例如,如果您將此數字設為過高的 200,則提示和團隊點數計數器將依此更新。

隊伍_分數_限制

local TEAM_SCORE_LIMIT = 200 -- 已更新行,請務必回返回
return TEAM_SCORE_LIMIT

這個簡單的變量更新在運行時發生,因為當回合開始時, ReplicatedStorage > HUDGuiSetup > 設置目標 需要 TEAM_SCORE_LIMIT 模組腳本,以便它可以在 UI 目標的 TextLabel 對物件中切換暫時器字串。

隊伍_分數_限制

local TEAM_SCORE_LIMIT = require(ReplicatedStorage.TEAM_SCORE_LIMIT)
local function setObjective(gui: ScreenGui)
local bodyTextLabel = gui.Objective.ObjectiveDisplay.Body.BodyTextLabel
bodyTextLabel.Text = bodyTextLabel.Text:format(TEAM_SCORE_LIMIT)
end

跟蹤點

現在玩家有了回合的目標,體驗需要追蹤每支隊伍的分數,直到他們達到目標為止。雖然 Teams的預設行為會自動將每個玩家加入他們的團隊,並將每個玩家的貢獻加到他們的團隊得分中,但對於回合制遊戲來說,存儲和監控點數在獨立位置是很重要的,因為如果玩家在回合結束前離開,他們的貢獻將被從排行榜中扣除,因為他們從體驗中斷時。

為了確保這不會發生,並保留對團隊目標的每一貢獻, 重複儲存 > HUDGui設定 > 開始同步團隊點數 將所有點數單獨存儲在 teamPoints 下的 Teams 標籤。作為 teamPoints 增量,此模組腳本呼叫功能 startSyncingTeamPoints 在目標 UI 組件內尋找團隊計數器 Class.GuiObjects

當它找到 TeamACounterTeamBCounter 時,它會獲得他們的 teamColor 特性,這與團隊生成區相關:TeamACounter 顯示綠色團隊的分數,TeamBCounter 跟蹤粉紅色團隊的分數。

開始同步團隊點數

local function startSyncingTeamPoints(gui: ScreenGui)
for _, teamPointCounter in gui.Objective.TeamPointCounter:GetChildren() do
if not teamPointCounter:IsA("GuiObject") then
continue
end
local iconTeamColor = teamPointCounter:GetAttribute(GuiAttribute.teamColor)

模組腳本然後呼叫其 功能來驗證團隊計數器的 mint 特性和團隊BC計數器的 carnation pink 特性都匹配相應的 屬性在服務下方。如果是這樣,它會返回兩個團隊。

開始同步團隊點數

local function getTeamFromTeamColor(teamColor: Color3): Team?
for _, team in Teams:GetTeams() do
if team.TeamColor == teamColor then
return team
end
end
return nil
end

當發生這種情況時, 將團隊計數器的 對象和團隊計數器的 對象設置為對應的 值,並且繼續更新它們,每當一名玩家由標記另一個隊伍的對手得分時。

開始同步團隊點數

teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)
team:GetAttributeChangedSignal(GuiAttribute.teamPoints):Connect(function()
teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)

目前這個部分的所有內容都專注於如何在玩家的屏幕上跟蹤點,但重要的是要檢查處理在服務器上跟蹤點的邏輯,以便知道團隊何時達到目標並贏得回合。如果您重新訪問 伺服器腳本服務 > 遊戲 > 評分 ,您可以看到模組腳本首先創建一個可綁定的事件,每次玩家得分一點時都會發射。

評分

local teamScoreChangedBindable = Instance.new("BindableEvent")
local Scoring = {
teamScoreChanged = teamScoreChangedBindable.Event,
}

然後呼叫 incrementScore 功能,執行以下行動:

  • 抓住玩家的隊伍和目前隊伍點數值在 Team 服務中的 Teams 對象,然後添加一個。
  • 抓取玩家在排行榜上的個人得分,並添加一個。
  • 發射之前提到的可綁定事件,包括玩家的隊伍和他們的分數。

這個過程有效地讓客戶端和伺服器對兩名玩家的個人得分和團隊得分保持一致。

評分

function Scoring.incrementScore(player: Player, amount: number)
local team = player.Team
assert(team, `Player {player.Name} must be on a team to score a point, but has no team`)
local teamPoints = team:GetAttribute(GuiAttribute.teamPoints)
teamPoints += amount
team:SetAttribute(GuiAttribute.teamPoints, teamPoints)
local leaderstat = player.leaderstats.Points
leaderstat.Value += amount
teamScoreChangedBindable:Fire(team, teamPoints)
end

顯示結果

隨著玩家標記對方並為他們的團隊得分, 服務器腳本服務 > 遊戲 > 回合 檢查是否滿足回合目標。如果他們的團隊得分低於 TEAM_SCORE_LIMIT 變量在 ReplicatedStorage > TEAM_SCORE_LIMIT 中,服務器將繼續等待直到其中一個團隊再次得分。

然而,一旦團隊的分數達到 TEAM_SCORE_LIMIT 變量,腳本會發出包含玩家名稱和他們隊伍的 roundWinnerRemote 事件實例。

回合

-- 檢查每次得分後回合是否結束
local team: Team
local score: number = 0
while score < TEAM_SCORE_LIMIT do
team, score = Scoring.teamScoreChanged:Wait()
end
-- 顯示獲勝團隊
for _, player in Players:GetPlayers() do
-- 在回合結束時向隊伍發送玩家所在的團隊
-- 因為玩家的隊伍即將被移除,因此客戶
-- 無法檢查自己的團隊
roundWinnerRemote:FireClient(player, team, player.Team)
end

每個客戶端上的 複製儲存 > 回合結果設定 腳本聆聽此 roundWinnerRemote 事件實例,因此它可以:

  • 顯示獨特的 StarterGui > RoundResultsGui UI 屏幕,宣布回合結果和玩家是否在勝利團隊伍中。
  • 播放勝利或擊敗音頻片段。

例如,如果玩家在得分的隊伍中,他們會收到形式多樣的回饋,回饋內容是回合結果的形式,即顯示勝利文字和播放愉快聲音的音頻片段。相反,如果玩家不在得分的隊伍中,他們將收到顯示擊敗文字的 UI 屏幕和播放陰森聲音的音頻片段。

勝利反饋
擊敗反饋
回合結果GUI設定

local function onRoundWinner(winner: Team, localTeam: Team?)
local victoryDefeatText = "Round ended!"
if localTeam then
-- 如果我們的團隊贏了,我們會顯示勝利!否則顯示擊敗...
local isVictory = winner == localTeam
if isVictory then
victorySound:Play()
victoryDefeatText = VICTORY_TEXT
else
defeatSound:Play()
victoryDefeatText = DEFEAT_TEXT
end
end

重設團隊

服務器腳本服務 > 遊戲 > 回合 檢查一支隊伍符合回合目標並啟動對每位玩家適當的用戶介面顯示之時,它也會將所有玩家從競技場傳送到大廳,通過關閉回合連接來實現。這會開始正式結束回合和重置兩支隊伍的過程。

在 設置生成位置 中使用相同的邏輯,回合 然後將 中立 生成地點置的 屬性設置為 真實,因此玩家無論他們的隊伍狀態況如何,都可以在那裡生成。這意味著大廳成為玩家在回合結束後可以重生的唯一位置。

回合

-- 將所有人送到大廳
playerAddedConnection:Disconnect()
neutralSpawn.Neutral = true
spawnPlayersInLobby(Players:GetPlayers())

在等待十秒鐘的中場休息後, 回合 服務器腳本將重新啟動循環,重置每個人的分數並將它們排序為新的團隊。樣本會再次重複這個循環回合過程,直到伺服器內沒有任何玩家。

現在玩家可以使用自己的團隊進入地圖進行全輪遊戲,下一個部分教你關於每個爆破器行為背後的腳本。