Remote Procedure Calls
簡介
遠程過程呼叫,簡稱RPC,是分享準時遊戲事件的理想選擇;相比之下,輸入結構和[Networked]
屬性是在不斷變化的網路客戶端之間分享狀態的首選解決方案。
例如,當玩家想與一個它沒有輸入權限的對象進行罕見的複雜交互時,例如使用他們庫存清單中的特定鑰匙來打開一扇鎖著的門。雖然從技術上講,這些動作可以通過包括額外的字段作為輸入的一部分來執行,但這將使輸入結構變得雜亂無章,並使其變得不容易操作。此外,Input Struct是作為不可靠的訊息發送的,也就是說,數據包可能會丟失。這對於需要連續輸入的東西(例如角色的移動)來說很少注意到,但是當這影響到玩家期望得到保証的單一的一次性動作時,就會對玩家的體驗造成傷害。在這種情況下,遠程程序呼叫是最好的做法。
設置
Fusion有一個簡單而強大的RPCs語法。總的來說,有3種類型的RPCs:
- 事件RPCs。
- 靜態RPC;以及,
- 有針對性的RPCs。
這些類型中的每一種都將在下面的章節中介紹。
事件RPC
要在NetworkObject
上的任何NetworkBehaviour
上定義一個RPC,只需遵循以下步驟:
- 宣告一個常規的CSharp方法,返回類型為
void
。 - 在方法宣告的前面添加
[Rpc]
屬性;以及, - 配置
RpcSources
和RpcTargets
參數,以控制RPC的呼叫地點和執行地點。
C#
[Rpc(source: RpcSources.InputAuthority, target: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color){
playerName = name;
playerColor = color;
}
一個RPC可以接受任何參數,並尊重Network Object > NetworkBehaviour > Networked State > Constraints
條目中概述的類型約束。
Note: 在方法上使用RPC_
前綴是一種慣例,以方便在代碼庫中搜索和識別RPC。
靜態RPC
靜態RPC遵循稍微不同的規則,它們:
- 忽略
RpcSources
和RpcTargets
參數;以及 - 要求方法的第一個參數是
NetworkRunner
。
C#
public static void Rpc_MyStaticRpc(NetworkRunner runner, int a) { }
RPC屬性參數
源頭和目標
RpcSources
和RpcTargets
是過濾器。RpcSources
定義了哪個對象可以發送RPC,而RpcTargets
定義了它的執行對象。
All
:可以被發送/被會話中的所有對象執行(包括伺服器)。Proxies
:可以被發送/由對該對象沒有輸入權限或狀態權限的對象執行。InputAuthority
:可以發送/由對該對象有輸入權限的對象執行。StateAuthority
:可以發送/由對該對象有狀態權限的對象執行。
IMPORTANT: RPCs沒有明確的狀態。設置RpcTargets.All
將__NOT__向晚加入的客戶傳送訊息,而斷開連接和重新連接的客戶將忘記它曾經發生過。因此,關鍵是要確保RPC是以下兩種情況之一:
- 真正瞬時的,沒有任何狀態的(例如聊天訊息);或者,
- 它的效果間接地記錄在
[Networked]
屬性中。
C#
public class Player : NetworkBehaviour {
[Networked] public string playerName { get; set; }
[Networked] public Color playerColor { get; set; }
[Rpc(RpcSources.InputAuthority, RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color) {
playerName = name;
playerColor = color;
}
}
可選的RPC屬性參數
除了強制性的RpcSources
和RpcTargets
屬性外,[Rpc]
屬性還提供了幾個可選參數。
Channel
(默認為Reliable
):如果RPC在傳輸中可能丟失,則設置為Unreliable
。InvokeLocal
(默認為true):如果RPC不在本地客戶端上呼叫,則設置為false。InvokeResim
(默認為false):如果RPC在重新模擬時不被呼叫,則設置為true。
C#
[Rpc (RpcSources.All, RpcTargets.All, InvokeLocal = true, InvokeResim = true )]
void RpcStartBoost(){
m_BoostAnim.StartBoostAnimation();
}
RPC方法參數
RpcInfo
RPC方法_declarations_可以接受一個RpcInfo
類型的可選參數。這允許讀出關於RPC的額外訊息。
Tick
:在哪個時間點發送的。Source
:哪個玩家(PlayerRef
)發送的。Channel
:它是作為Unreliable
還是可靠
的RPC發送的。IsInvokeLocal
:最初呼叫這個RPC的是本地玩家。
C#
[Rpc(source: RpcSources.InputAuthority, target: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
playerName = name;
playerColor = color;
}
該參數_always_被宣告為RpcInfo info = default
。
有針對性的Rpc
當一個RPC要在特定玩家的機器上專門執行時,就會使用所謂的目標RPC。事件RPC和靜態RPC都可以變成目標RPC,方法是在[RpcTarget]
屬性前添加一個PlayerRef
參數。一個典型的用例是團隊聊天,一個消息只針對自己團隊中的特定玩家。
C#
[Rpc(source: RpcSources.InputAuthority, target: RpcTargets.StateAuthority)]
public void Rpc_TargetedInstanceMessage([RpcTarget] PlayerRef player, string message){}
public static void Rpc_MyTargetedStaticMessage(NetworkRunner runner, [RpcTarget] PlayerRef player, string message) { };
IMPORTANT: 在方法宣告中使用的[RpcTarget]
屬性與方法宣告前的[Rpc]
屬性中的RpcTargets
參數是不同的。