This document is about: FUSION 1
SWITCH TO

Weapons & Shooting

Level 4

概述

Weapons元件負責處理玩家武器。它維持一個目前武器的清單,處理武器切換。除此之外,它針對常用武器動作比如FireReload來提供一個介面。可以拾取武器物件或把它們丟棄到地面,請參見武器丟棄章節以取得更多資訊。

針對武器,有兩個基礎層級:WeaponWeaponFirearmWeapon持有裸機武器最小值,並且WeaponFirearm封裝基礎槍炮功能性,比如發射邏輯、彈匣處理、散佈,及後座力。

Fusion BR中的武器及拋射物大多基於即時命中判定功能性,因為這對於本專案來說很方便。如需取得關於武器及拋射物的更詳細的方法或關於不同的拋射物方法的更詳細的文檔,請參見Fusion拋射物基礎Fusion拋射物進階範例。

即時命中判定武器

即時命中判定武器是遊戲中的主要武器。當發射時,即時命中判定武器使用射線來評估命中。不會針對拋射物來繁衍網路物件,而是只有在一個環形緩衝中儲存一個小的ProjectileData架構,以計算同儕節點上的視覺效果。即時命中判定武器可以選擇建立一個虛擬的純視覺效果拋射物,其飛向目標(請查看DummyProjectile指令碼)。

C#

public struct ProjectileData : INetworkStruct
{
    public Vector3 Destination;
    [Networked, Accuracy(0.01f)]
    public Vector3 ImpactNormal { get; set; }
    public int     ImpactTagHash;
}

[Networked, Capacity(25)]
private NetworkArray<ProjectileData> _projectileData { get; }

拋射物武器

拋射物武器(ProjectileWeaponThrowableWeapon)繁衍隨著時間移動的獨立拋射物物件。拋射物在每個模擬刷新時在它們先前的位置及新的位置之間執行短射線。在這個專案中,拋射物武器只用於手榴彈。如需取得更深入的執行方式資訊,請參見Fusion拋射物基礎Fusion拋射物進階範例。

後座力

武器後座力是一個常見的遊戲行為,其基於真實的武器行為,也就是武器在連續射擊時傾向於往上瞄準。通常在遊戲中的武器遵循一個固定的或半隨機的路徑,玩家可以透過大量遊玩來學習及形成肌肉記憶,這讓玩家能夠以他們的輸入來抵消後座力效果。

Fusion BR附有一個後座力系統。每個武器可以指派一個後座力模式(也稱為 散射模式)。後座力模式是一個可指令碼物件,其在連續射擊時定義武器的路徑。後座力直接影響玩家查看旋轉,並且玩家可以對抗它。對抗過程被稱為 後座力減少,並且您可以在Agent指令碼中的SetLookRotation方法中找到它。在停止射擊後,查看旋轉自動回到初始值。

recoil pattern
當沒有散佈的發射時的後座力模式及實際的子彈孔

後座力模式定義了一個序列中的每個子彈的準確位置。在初始後座力序列(後座力起始值)完成後,後座力遵循一個無限迴圈(後座力無限值)。

請注意武器散佈應用於後座力位置的頂層,所以基於散佈值,仍然有一些射擊隨機性。

動態散佈

每個槍炮武器有一個散佈行為設定。

weapon dispersion

散佈在連續發射時增加,並且在停止發射後自動降低到預設值。角色的狀態(奔跑、飛行、瞄準)會進一步增加或減少武器散佈。

weapon dispersion
散佈及後座力設定

穿破

拋射物穿破(也稱為穿透)是在遊戲世界中射擊並穿透特定物件的能力。這通常附有一個損傷效果。

當在HitscanWeapon中處理命中時直接計算穿破。每個拋射物可以被指派一個穿破設定,其針對不同的材質來指定一個損傷乘數值。拋射物在一個為零的損傷乘數值時並不穿透一個物件。材質基於被指派到遊戲物件的Unity標籤而有所差異,並且基於標籤上的雜湊而在運行階段被檢查。

piercing setup

損傷下降

隨著發射原始地的距離而有拋射物損傷下降。損傷下降是由DummyProjectile元件中定義的設定來控制。

dummy projectile

第三人射擊

第三人射擊需要處理在遊戲世界中,玩家透過相機所看見的,以及玩家角色從它們的位置可以實際命中的,之間的差異。

當計算命中時,我們首先需要知道目標點。目標點指定了玩家正在瞄準的位置,並且透過從每個FixedUpdateNetwork的武器的指令碼中的相機來直接發射一個射線,來計算目標點的位置。當處理發射輸入時,武器將獲取目標點,並從角色發射位置向目標點射擊另一個射線,以獲得實際命中。

third person shooting
第三人射擊圖表
注意事項:發射位置不在槍管末端。最初我們使用槍管位置,但因為武器位置受到動畫影響,在快速移動(如掃射)時的發射體驗會不太穩定。因此,我們切換為一個靠近角色肩膀的固定發射位置。

在這些基礎計算的頂層,有一些額外的改進,以獲得一個更好的射擊體驗:

  • 當玩家的角色不能到達目標點時,顯示紅色十字以表示實際著陸點
red cross
當不能到達目標點時,顯示紅色十字
  • 從發射位置到目標點的射線,忽略了不靠近發射位置或目標點的環境命中,以減少我們稱為 角落問題 的問題行為。這極大地改善了角落、樹木,及其他物件周圍的射擊行為。玩家實際上是向十字形狀指向的地方射擊——但如果玩家瞄準的地方是角落附近,則引入一個小的邊界以射擊在角落之後的玩家。這個忽略行為可以在所有拋射物計算所使用的ProjectileUtility中找到。
corner issue
拋射物將忽略角落以到達目標點
  • 當目標點靠近玩家角色,並且到目標點的方向與角色向前的方向之間的角度太大時,目標點將改為以向前方向的一些距離來計算。
angle ignore
如果到達十字形狀的角度太大,武器向前射擊

拋射物

在Fusion BR中不是大量使用隨著時間而在遊戲世界中移動的拋射物,例外是手榴彈。請查看Fusion拋射物基礎Fusion拋射物進階範例以取得更精細的拋射物示例。

手榴彈

在物品箱中可以找到手榴彈。當裝備一個手榴彈時,一個小的倒數計時器將減少手榴彈的引爆時間,直到達到一個特定的最小值(請參見ThrowableWeapon)。手榴彈拋射物由特殊武器來處理,如同從一個隱形的手榴彈發射器發射出去一樣。

注意事項:玩家可以用字母數字鍵4來輪換手榴彈。

爆炸性手榴彈

繁衍一個爆炸物件的手榴彈。

explosive grenade

閃光彈

當這個手榴彈引爆時,如果在特定距離內的玩家朝著手榴彈的方向看,就會導致失明。在AgentSenses元件中計算簡單的玩家失明效果。

flash grenade

煙霧彈

繁衍一個煙霧效果的手榴彈。

smoke grenade

健康及損傷系統

在建立HitData架構的HitUtility中處理每個命中,並且損傷會乘上可能的身體部位乘數。BodyPart是預設延遲補償Hitbox的一個下層層級,附加了一個損傷乘數(比如,頭有一個比1高的乘數,而四肢有一個比1低的乘數)。然後由目標的Health元件來處理HitData

健康元件建立一個BodyHitData架構,其只附有必要的資訊以同步命中到所有客戶端。命中儲存在BodyHitData架構的一個小的已連線的環形緩衝之中。

C#

public struct BodyHitData : INetworkStruct
{
    public EHitAction Action;
    public float      Damage;
    [Networked, Accuracy(0.01f)]
    public Vector3    RelativePosition { get; set; }
    [Networked, Accuracy(0.01f)]
    public Vector3    Direction { get; set; }
    public PlayerRef  Instigator;
}

[Networked, Capacity(8)]
private NetworkArray<BodyHitData> _hitData { get; }
注意事項:請注意命中的RelativePosition如何儲存在BodyHitData之中,而非一個絕對位置。由於代理的位置是在從伺服器接收到的最後兩個刷新之間進行內插補點,因此相對位置更適合來放置命中效果,比如血液正確地飛濺到身體上。

基於命中緩衝中的改變,將觸發適當的命中反應——在UI中的命中方向、顯示命中確認及數量給損傷發動者、血液效果的繁衍。

當一名玩家命中另一名玩家,子彈的衝擊和命中效果(血液)將立即顯示。然而,命中確認(在UI中的紅色十字及命中數量)在命中作為新伺服器狀態的一部分被接收(命中被伺服器「確認」)後,才會顯示給玩家。這帶來一個小的延遲(基於網路情況),但確保只有有效的命中可以呈現給玩家。
Back to top