實現 Blaster 行為

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

實現衝刺行為的實現 是程式設計的爆破機械人體驗的過程。雖然玩家可以用一次點擊或按鈕來爆炸,但創造一個滿意和準確的爆炸行為很重要,因為它能強化玩家對整個遊遊玩的享受。

使用 示例雷射標籤體驗 作為參考,這個教學的第二部分教你關於兩種不同類型的雷射的實現方法,包括關於:

  • 偵測玩家按下爆炸按鈕時間。
  • 檢查玩家是否可以使用他們的爆破按鈕,如果他們剛剛按下了爆破按鈕。
  • 生成爆炸資料,告訴伺服器誰啟動了爆炸、它從哪裡來的,並且每個雷射光束的最終目的地是什麼。
  • 通知伺服器爆炸資料,以便它能夠在爆炸與其他玩家碰撞時執行相關操作。
  • 在每次爆炸之間重置噴射機,讓噴射機有足夠的時間來冷卻,再次爆炸時才能再次爆炸。

完成此部分後,您將了解允許槍枝撞擊其他玩家時檢測到的指令碼,然後根據槍枝輸入型對應的各種健康進行減少。

偵測玩家輸入

要實現衝擊行為的第一個步驟是聆聽玩家使用爆炸按鈕時發生的事件。 玩家使用的輸入類型取決於他們使用的裝置來存取體驗。 舉例來說, ReplicatedStorage > 用戶輸入處理器 支援滑鼠和鍵盤控制、遊戲

此客戶端腳本使用 ContextActionService 來將 MouseButton1ButtonR2 綁定到爆破動作動。這意味著每次玩家按下左鍵滑鼠按鈕或遊戲手柄的 R2 按鈕時,都

用戶輸入處理器

ContextActionService:BindAction("_", onBlasterActivated, false,
Enum.UserInputType.MouseButton1,
Enum.KeyCode.ButtonR2
)

另一個重要的注意事項是在 Enum.UserInputState.Begin 定義中使用 onBlasterActivated()。許多用戶界面交互,例如選擇這個示例中的一個噴射器,在滑鼠按鈕出現(Enum.UserInputState.End)後才會發生。這種爆�

要示範,您可以將 Enum.UserInputState.Begin 變更為 Enum.UserInputState.End ,然後玩測試以確認爆炸對遊戲體驗的影響。例如,如果玩家可以按住按鈕 without triggering the blast,會如何改變他們的體驗標籤其他玩家?

用戶輸入處理器

local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- 更新了線條,請務必還返回
attemptBlastClient()
end
end

檢查玩家是否可以爆炸

UserInputHandler 檢測到按鈕或螢伺服器點擊後,會呼叫 ReplicatedStorage >

可以本地玩家爆炸

local function canLocalPlayerBlast(): boolean
return localPlayer:GetAttribute(PlayerAttribute.blasterStateClient) == BlasterState.Ready
end

這次暫停會讓您無法像此樣快地點擊。例如,如果您將功能變更為「總是返回」,您就可以快地點擊您的雷射標籤,而不會有延遲,這對於雷射標籤遊玩來說是不現實的。

可以本地玩家爆炸

local function canLocalPlayerBlast(): boolean
return true -- 更新了線條,請務必還返回
end

生成爆炸資料

在確認玩家的激光器在 Ready 狀態後,attemptBlastClient 呼叫 ReplicatedStorage > 1>attemptBlastClient1> > 4>blastClient4>。第一

下一步是生成爆炸資料。如果您檢查 ReplicatedStorage > Blaster > BlastData ,您可以看到每個爆炸包含三個信息碎片:

  • 爆炸的玩家。
  • Delta.CFrame 代表爆炸的起始點。
  • 一個 RayResult 桌子,包含每個雷射光束的最終目的地和命中玩家,如果命中其他玩家。

要生成此資料,blastClient 呼叫ReplicatedStorage > attemptBlastClient > 2> blastClient2> > 5> generateBlastData5>,您可以在下面檢視。

生成爆炸資料

local function generateBlastData(): BlastData.Type
local blasterConfig = getBlasterConfig()
local rayDirections = getDirectionsForBlast(
currentCamera.CFrame, blasterConfig)
local rayResults = castLaserRay(
localPlayer, currentCamera.CFrame.Position, rayDirections)
local blastData: BlastData.Type = {
player = localPlayer,
originCFrame = currentCamera.CFrame,
rayResults = rayResults,
}
return blastData
end

此功能使用 getBlasterConfig 來取回玩家的雷射類輸入。範例提供兩種雷射類型:一個生產多個光束並且寬涵垂直掃射的雷型,另一個生產單一光束。您可以在 ReplicatedStorage > Instances > 1> LaserBlastersFolder1> 中找到他們的設定。

然後, function 使用 currentCamera.CFrame 作為爆炸的起始點,將它傳到 getDirectionsForBlast 。在這個時候,代碼不再是關於爆炸

通知伺服器

一旦 blastClient 有完整資料對爆炸,它會發生兩個事件:

爆破客戶

local laserBlastedBindableEvent = ReplicatedStorage.Instances.LaserBlastedBindableEvent
local laserBlastedEvent = ReplicatedStorage.Instances.LaserBlastedEvent
laserBlastedBindableEvent:Fire(blastData)
laserBlastedEvent:FireServer(blastData)

Class.BindableEvent 通知其他客戶腳本衝擊的時間。例如, ReplicatedStorage > FirstPersonBlasterVisuals 使用此事件來知道當衝擊動畫和冷卻條綫時顯

雷射爆破處理器

local function onLaserBlastedEvent(playerBlasted: Player, blastData: BlastData.Type)
local validatedBlastData = getValidatedBlastData(playerBlasted, blastData)
if not validatedBlastData then
return
end
if not canPlayerBlast(playerBlasted) then
return
end
blastServer(playerBlasted)
processTaggedPlayers(playerBlasted, blastData)
for _, replicateToPlayer in Players:GetPlayers() do
if playerBlasted == replicateToPlayer then
continue
end
replicateBlastEvent:FireClient(replicateToPlayer, playerBlasted, blastData)
end
end

為了幫助防止作弊,伺服器必須確認每個客戶端傳送的所有資料。這些檢查包括:

  1. BlastData 是否是表?它包含 Class.CFrame 和另一個名為 rayResults 的表?
  2. 玩家有沒有裝備一把槍械?
  3. 玩家有世界內的角色和位置嗎?
  4. 在發送爆炸資料後,玩家移動了超出範圍的距離,以從哪裡爆炸雷射光束?

這個最後的測試涉及審判調用,並且根據伺服器的延遲和玩家的移動速度,您可能會決定其他值對於您自己的體驗是否過度。要示範這個審判調用,您可以從 getValidatedBlastData 中獲得一個打印聲明,並且測試體驗。

取得驗證爆炸資料

local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Position
print(distanceFromCharacterToOrigin.Magnitude) -- 更新了線條,請務必移除
if distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS then
warn(`Player {player.Name} failed an origin sanity check while blasting`)
return
end

隨著您移動和爆炸,記錄輸出。它可能看起來像這樣:


1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

如果您在 ReplicatedStorage > PlayerStateHandler > togglePlayerMovement 中增加移動速度,玩家可能會在爆炸之間發生多個失敗的檢查。

切換玩家移動

local ENABLED_WALK_SPEED = 60 -- updated line, be sure to change back

伺服器接下來會做追蹤中:

  • 驗證 rayResults
  • 檢查玩家是否可以爆炸。
  • 重設武器狀態。
  • 降低任何標籤的玩家的生命值。
  • 重複爆炸,讓其他玩家可以看到第三人稱視圖。

有關此伺服器操作的更多資訊,請參閱檢測擊中 部分的教學。

重置雷管

在示例雷射標籤體驗中,雷射使用熱力學。在一個預設的爆炸後重新裝彈,而不是在每次爆炸之後等待時間,這會導致延遲在客戶端 ( blastClient 和服務器 ( blastServer ) 之間的冷卻時間。這個冷卻時間延遲會在服務器 ( blast

爆破伺服器

local blasterConfig = getBlasterConfig(player)
local secondsBetweenBlasts = blasterConfig:GetAttribute("secondsBetweenBlasts")
task.delay(secondsBetweenBlasts, function()
local currentState = player:GetAttribute(PlayerAttribute.blasterStateServer)
if currentState == BlasterState.Blasting then
player:SetAttribute(PlayerAttribute.blasterStateServer, BlasterState.Ready)
end
end)

secondsBetweenBlasts 屬性是 ReplicatedStorage > Instances > 1> LaserBlastersFolder1> 的一部分。 在 4>secondsBetweenBlasts4> 延遲通過後,玩家可以再次爆炸,並且整個過程重複。 為了幫助玩

在這個時候,玩家可以重生並重生,瞄準和爆炸,但體驗仍然必須決定每次爆炸的結果。 在教學的下一個部分,你會學會程式設計能夠讓 Blaster 偵測到其他玩家的爆炸時殺死人數,然後減少 Blaster 設定的適當人數。