Weapons & Shooting
概述
Weapons
元件負責處理玩家武器。它維持一個目前武器的清單,處理武器切換。除此之外,它針對常用武器動作比如Fire
及Reload
來提供一個介面。可以拾取武器物件或把它們丟棄到地面,請參見武器丟棄章節以取得更多資訊。
針對武器,有兩個基礎層級:Weapon
及WeaponFirearm
。Weapon
持有裸機武器最小值,並且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; }
拋射物武器
拋射物武器(ProjectileWeapon
、ThrowableWeapon
)繁衍隨著時間移動的獨立拋射物物件。拋射物在每個模擬刷新時在它們先前的位置及新的位置之間執行短射線。在這個專案中,拋射物武器只用於手榴彈。如需取得更深入的執行方式資訊,請參見Fusion拋射物基礎及Fusion拋射物進階範例。
後座力
武器後座力是一個常見的遊戲行為,其基於真實的武器行為,也就是武器在連續射擊時傾向於往上瞄準。通常在遊戲中的武器遵循一個固定的或半隨機的路徑,玩家可以透過大量遊玩來學習及形成肌肉記憶,這讓玩家能夠以他們的輸入來抵消後座力效果。
Fusion BR附有一個後座力系統。每個武器可以指派一個後座力模式(也稱為 散射模式)。後座力模式是一個可指令碼物件,其在連續射擊時定義武器的路徑。後座力直接影響玩家查看旋轉,並且玩家可以對抗它。對抗過程被稱為 後座力減少,並且您可以在Agent
指令碼中的SetLookRotation
方法中找到它。在停止射擊後,查看旋轉自動回到初始值。
後座力模式定義了一個序列中的每個子彈的準確位置。在初始後座力序列(後座力起始值)完成後,後座力遵循一個無限迴圈(後座力無限值)。
請注意武器散佈應用於後座力位置的頂層,所以基於散佈值,仍然有一些射擊隨機性。
動態散佈
每個槍炮武器有一個散佈行為設定。
散佈在連續發射時增加,並且在停止發射後自動降低到預設值。角色的狀態(奔跑、飛行、瞄準)會進一步增加或減少武器散佈。
穿破
拋射物穿破(也稱為穿透)是在遊戲世界中射擊並穿透特定物件的能力。這通常附有一個損傷效果。
當在HitscanWeapon
中處理命中時直接計算穿破。每個拋射物可以被指派一個穿破設定,其針對不同的材質來指定一個損傷乘數值。拋射物在一個為零的損傷乘數值時並不穿透一個物件。材質基於被指派到遊戲物件的Unity標籤而有所差異,並且基於標籤上的雜湊而在運行階段被檢查。
損傷下降
隨著發射原始地的距離而有拋射物損傷下降。損傷下降是由DummyProjectile
元件中定義的設定來控制。
第三人射擊
第三人射擊需要處理在遊戲世界中,玩家透過相機所看見的,以及玩家角色從它們的位置可以實際命中的,之間的差異。
當計算命中時,我們首先需要知道目標點。目標點指定了玩家正在瞄準的位置,並且透過從每個FixedUpdateNetwork
的武器的指令碼中的相機來直接發射一個射線,來計算目標點的位置。當處理發射輸入時,武器將獲取目標點,並從角色發射位置向目標點射擊另一個射線,以獲得實際命中。
在這些基礎計算的頂層,有一些額外的改進,以獲得一個更好的射擊體驗:
- 當玩家的角色不能到達目標點時,顯示紅色十字以表示實際著陸點
- 從發射位置到目標點的射線,忽略了不靠近發射位置或目標點的環境命中,以減少我們稱為 角落問題 的問題行為。這極大地改善了角落、樹木,及其他物件周圍的射擊行為。玩家實際上是向十字形狀指向的地方射擊——但如果玩家瞄準的地方是角落附近,則引入一個小的邊界以射擊在角落之後的玩家。這個忽略行為可以在所有拋射物計算所使用的
ProjectileUtility
中找到。
- 當目標點靠近玩家角色,並且到目標點的方向與角色向前的方向之間的角度太大時,目標點將改為以向前方向的一些距離來計算。
拋射物
在Fusion BR中不是大量使用隨著時間而在遊戲世界中移動的拋射物,例外是手榴彈。請查看Fusion拋射物基礎及Fusion拋射物進階範例以取得更精細的拋射物示例。
手榴彈
在物品箱中可以找到手榴彈。當裝備一個手榴彈時,一個小的倒數計時器將減少手榴彈的引爆時間,直到達到一個特定的最小值(請參見ThrowableWeapon
)。手榴彈拋射物由特殊武器來處理,如同從一個隱形的手榴彈發射器發射出去一樣。
爆炸性手榴彈
繁衍一個爆炸物件的手榴彈。
閃光彈
當這個手榴彈引爆時,如果在特定距離內的玩家朝著手榴彈的方向看,就會導致失明。在AgentSenses
元件中計算簡單的玩家失明效果。
煙霧彈
繁衍一個煙霧效果的手榴彈。
健康及損傷系統
在建立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中的命中方向、顯示命中確認及數量給損傷發動者、血液效果的繁衍。