Remote Procedure Calls (PRC) - cheona-thousand-man/Unity-myBasics-Wiki GitHub Wiki
๊ฐ์
- ์๊ฒฉ ํ๋ก์์ ํธ์ถ(RPC) ๊ฒ์ ์ด๋ฒคํธ๋ฅผ ๊ณต์ ํ๋ ๋ฐ ์ ํฉ
- Input Struct์ [Networked] ์์ฑ ์ง์์ ์ผ๋ก ๋ณํํ๋ ๋คํธ์ํฌ ํด๋ผ์ด์ธํธ ๊ฐ์ ์ํ๋ฅผ ๊ณต์ ํ๋ ๋ฐ ์ ํฉ
์๋ฅผ ๋ค์ด ํ๋ ์ด์ด๊ฐ ์ธ๋ฒคํ ๋ฆฌ์์ ํน์ ํค๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ธด ๋ฌธ์ ์ฌ๋ ๋๋ฌธ ๋ณต์กํ ์ํธ์์ฉ์ ์ํํ๊ณ ์ ํ ๋,
- ์ด๋ฅผ Input Authority๊ฐ ์๋ ๊ฐ์ฒด์ ์ํธ์์ฉํ๋ ๊ฒฝ์ฐ์ RPC๊ฐ ์ ํฉ
- Input Struct์ ์ถ๊ฐ ํ๋๋ฅผ ํฌํจ์์ผ ์ด๋ฌํ ์์ ์ ๊ธฐ์ ์ ์ผ๋ก ์ํํ ์ ์์ง๋ง, ์ด๋ Input Struct ๊ตฌ์กฐ ๋ณต์กํ
- Input Struct๋ ์ ๋ขฐํ ์ ์๋ ๋ฉ์์ง๋ก ์ ์ก๋๋ฉฐ, ํ๋ ์ด์ด๊ฐ ๊ธฐ๋ํ๋ ๋จ์ผ ์ผํ์ฑ ์์ ์ ์ํฅO (์ง์์ ์ธ ์ ๋ ฅ(์: ์บ๋ฆญํฐ ์ด๋)์๋ ํฐ ๋ฌธ์ X)
Setup
- ์ธ์คํด์ค RPC
- ์ ์ RPC
- ๋์ ์ง์ RPC
Instance RPC
NetworkObject
์ NetworkBehaviour
์์ RPC
์ ์
void
๋๋RpcInvokeInfo
๋ฐํ ํ์์ ์ผ๋ฐ C# ๋ฉ์๋ ์ ์ธ- ๋ฉ์๋ ์ด๋ฆ ์์ด๋ ๋ค์
RPC
์ถ๊ฐ(๋์๋ฌธ์ ๊ตฌ๋ถ ์์) - ๋ฉ์๋ ์ ์ธ ์์
[Rpc]
์์ฑ์ ์ถ๊ฐ RpcSources
๋ฐRpcTargets
๋งค๊ฐ๋ณ์๋ฅผ ๊ตฌ์ฑํ์ฌ RPC๋ฅผ ํธ์ถํ ์ ์๋ ์์น์ ์คํ๋๋ ์์น ์ ์ด
[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
playerName = name;
playerColor = color;
}
Static RPC
์ฝ๊ฐ ๋ค๋ฅธ ๊ท์น ์ค์
- RpcSources ๋ฐ RpcTargets ๋งค๊ฐ๋ณ์ ๋ฌด์
- ๋ฉ์๋์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก NetworkRunner ์๊ตฌ
- ํน์ NetworkObject์ ๋ฐ์ธ๋ฉ๋์ง ์์ผ๋ฏ๋ก SimulationBehaviour์ ๊ตฌํ ๊ฐ๋ฅ
[Rpc]
public static void Rpc_MyStaticRpc(NetworkRunner runner, int a) { }
RPC ์์ฑ ๋งค๊ฐ๋ณ์ (ํ์)
- RpcSources RPC๋ฅผ ๋ณด๋ผ ์ ์๋ Peer๋ฅผ ์ ์
- RpcTargets ์คํ๋๋ Peer๋ฅผ ์ ์
- All ์ธ์ ์ ๋ชจ๋ ํผ์ด(์๋ฒ ํฌํจ)๊ฐ ๋ณด๋ผ ์ ์์ผ๋ฉฐ ์คํ๋ฉ๋๋ค.
- Proxies ๊ฐ์ฒด์ Input Authority ๋๋ State Authority๊ฐ ์๋ ํผ์ด๊ฐ ๋ณด๋ผ ์ ์์ผ๋ฉฐ ์คํ๋ฉ๋๋ค.
- InputAuthority ๊ฐ์ฒด์ Input Authority๊ฐ ์๋ ํผ์ด๊ฐ ๋ณด๋ผ ์ ์์ผ๋ฉฐ ์คํ๋ฉ๋๋ค.
- StateAuthority ๊ฐ์ฒด์ State Authority๊ฐ ์๋ ํผ์ด๊ฐ ๋ณด๋ผ ์ ์์ผ๋ฉฐ ์คํ๋ฉ๋๋ค.
RPC์๋ ๋ช ์์ ์ธ ์ํ๊ฐ ์์ต๋๋ค. ๋์ค์ ์ฐธ๊ฐํ ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ์ด ๋๊ฒผ๋ค๊ฐ ๋ค์ ์ฐ๊ฒฐ๋ ํด๋ผ์ด์ธํธ๋ RPC๊ฐ ๋ฐ์ํ ์ฌ์ค์ ์์ด๋ฒ๋ฆฝ๋๋ค. ๋ฐ๋ผ์ RPC๊ฐ ๋ ์ค ์ด๋ ์ํ์ธ์ง ํ์ธ ํ์ํฉ๋๋ค.
- ์ง์ ํ ์ผํ์ฑ ์ํ(์: ์ฑํ ๋ฉ์์ง)์ธ์ง
- [Networked] ์์ฑ์ ๊ฐ์ ์ ์ผ๋ก ๊ธฐ๋ก๋ ์ํฅ์ ๊ฐ์ง๋์ง
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 ์์ฑ ๋งค๊ฐ๋ณ์
- Channel(๊ธฐ๋ณธ๊ฐ Reliable) RPC๊ฐ ์ ์ก ์ค ์์ค๋ ์ ์๋ ๊ฒฝ์ฐ Unreliable๋ก ์ค์
- InvokeLocal(๊ธฐ๋ณธ๊ฐ true) RPC๊ฐ ๋ก์ปฌ ํด๋ผ์ด์ธํธ์์ ํธ์ถ๋ ์ง ์ฌ๋ถ
- InvokeResim(๊ธฐ๋ณธ๊ฐ false) ์ฌ์๋ฎฌ๋ ์ด์ ์ค์ RPC๊ฐ ํธ์ถ๋ ์ง ์ฌ๋ถ
- TickAligned(๊ธฐ๋ณธ๊ฐ true) RPC๊ฐ ์ ์ก๋ ํฑ์์ ๋๋ ์ดํ์ RPC๋ฅผ ์คํํ ์ง ์ฌ๋ถ ์ค์
[Rpc (RpcSources.All, RpcTargets.All, InvokeLocal = true, InvokeResim = true, TickAligned = false )]
void RpcStartBoost(){
m_BoostAnim.StartBoostAnimation();
}
RPC ๋ฉ์๋ ๋งค๊ฐ๋ณ์
RPC๋ ๋ฐํ์์ ์ง๋ ฌํ๋๋ฏ๋ก ์ผ๋ฐ์ ์ธ CLR ํ์ (e.g.: bool)์ ์ฌ์ฉํ๋ ๊ฒ์ด Fusion ํน์ ์ ํ์ (e.g. NetworkBool)๋ณด๋ค ๊ถ์ฅ
ํ์ฉ๋๋ ๋ฐ์ดํฐ ๋งค๊ฐ๋ณ์
์์ ํ์
byte, sbyte, Int16, Int32, Int64, UInt16, UInt32, UInt64, float, doubleUnity ๊ตฌ์กฐ์ฒด ํ์
Vector2, Vector3, Vector4, Quaternion, Matrix4x4, Vector2Int, Vector3Int, BoundingSphere, Bounds, Rect, BoundsInt, RectInt, Color, Color32- System.Guid
- ์ฌ์ฉ์ ์ ์ INetworkStructs
Fusion ์ ์ INetworkStructs
NetworkString, NetworkBool, Ptr, Angle, BitSet64, BitSet128, BitSet192, BitSet256, PlayerRefSet, NetworkId, NetworkButtons, NetworkRNG, NetworkObjectGuid, NetworkObjectHeader, NetworkPrefabRef, NetworkPrefabId, SceneRef, TickTimer, IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)Fusion ํ์
NetworkObject (NetworkId๋ก ์ง๋ ฌํ๋จ), NetworkBehaviour (NetworkId์ NetworkBehaviour ์ธ๋ฑ์ค๋ก ์ง๋ ฌํ๋จ), PlayerRef (PlayerRef.PlayerId๋ก ์ง๋ ฌํ๋จ)- String
- ์์ ๋์ด๋ ํ์
์
๋ฐฐ์ด
RpcInfo (์ ํ)
RPC ๋ฉ์๋ ์ ์ธ์์ RPC ๋ฉํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ RpcInfo ์ฌ์ฉ ๊ฐ๋ฅ
- Tick ์ ์ก๋ Tick
- Source ์ด๋ฅผ ๋ณด๋ธ ํ๋ ์ด์ด(PlayerRef)
- Channel Unreliable ๋๋ Reliable๋ก ์ ์ก๋์๋์ง ์ฌ๋ถ
- IsInvokeLocal ์ด RPC๋ฅผ ๋ก์ปฌ ํ๋ ์ด์ด๊ฐ ํธ์ถํ๋์ง ์ฌ๋ถ
[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
playerName = name;
playerColor = color;
}
๋งค๊ฐ๋ณ์๋ ํญ์ RpcInfo info = default๋ก ์ ์ธ
Server vs Host Source
- [Server Mode] ์๋ฒ์์ ๋ณด๋ธ RPC์ ํฌํจ๋ RpcInfo.Source๋ PlayerRef.None์ผ๋ก ์ค์
- [Host Mode]
- ํธ์คํธ-ํด๋ผ์ด์ธํธ๋ ์๋ฒ์ ํ๋ ์ด์ด ๋ ๋ค ์คํ
- ๊ธฐ๋ณธ์ ์ผ๋ก ํธ์คํธ๊ฐ ๋ณด๋ธ RPC๋ ์๋ฒ์ ๋์ผํ๊ฒ ์๋ํ์ฌ RpcInfo.Source๋ฅผ PlayerRef.None์ผ๋ก ์ค์
- ํธ์คํธ์ ๋ก์ปฌ PlayerRef๋ฅผ ํฌํจํ๋ ค๋ฉด HostMode ์์ฑ์ RpcHostMode.SourceIsHostPlayer๋ก ์ค์
HostMode๋ ๋ค์ ๋ ๋ชจ๋ ์ค ํ๋๋ก ์ค์
- RpcHostMode.SourceIsServer (๊ธฐ๋ณธ๊ฐ) RpcInfo.Source๊ฐ PlayerRef.None์ผ๋ก ์ค์
- RpcHostMode.SourceIsHostPlayer Fusion์ด HostMode๋ก ์คํ๋ ๋ RpcInfo.Source๊ฐ ๋ก์ปฌ PlayerRef๋ก ์ค์
ํธ์คํธ์ PlayerRef๋ฅผ RpcSource.Info์ ํฌํจํ๊ธฐ ์ํด ์ด์ ์ฝ๋๋ฅผ ์์์ ๊ฐ์ด ์์
[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority, HostMode = RpcHostMode.SourceIsHostPlayer)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
playerName = name;
playerColor = color;
}
RpcInvokeInfo (์ ํ)
RPC ๋ฉ์๋๋ ๋ฐํ๊ฐ์ผ๋ก RPC ํธ์ถ ๋ฐ ์ ์ก ์์
์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด RpcInvokeInfo
๋ฅผ ๋ฐํ ๊ฐ์ผ๋ก ์ ์ ๊ฐ๋ฅ
- LocalInvokeResult ๋ก์ปฌ ํธ์ถ ์์ ์ ์ฑ๊ณต ์ฌ๋ถ ๋๋ ์คํจ ์์ธ์ ๋ํ๋ด๋ RpcLocalInvokeResult ์ด๊ฑฐํ ๊ฐ
- SendCullResult ์๊ฒฉ ํผ์ด์ ๋ํ RPC ํธ์ถ์ ์ฑ๊ณต ์ฌ๋ถ ๋๋ ์คํจ ์์ธ์ ๋ํ๋ด๋ RpcSendCullResult ์ด๊ฑฐํ ๊ฐ
- SendResult RPC ์ ์ก ์์ ์ ๋ํ ๋ฉํ ์ ๋ณด๋ฅผ ํฌํจํ๋ RpcSendResult ๊ตฌ์กฐ์ฒด
- Result RPC ๋ฉ์์ง ์ ์ก ์์ ์ ๊ฒฐ๊ณผ ํ๋๊ทธ๋ฅผ ๋ํ๋ด๋ RpcSendMessageResult
- MessageSize RPC ํจํค์ง์ ํฌ๊ธฐ
- Receivers ์ด RPC ์์ ์ ์์ ์๋ก ํฌํจ๋ PlayerRefs ์ปฌ๋ ์
- CulledReceivers ์ด RPC ์ ์ก ์์ ์์ ์ ์ธ๋ PlayerRefs ์ปฌ๋ ์
์ฐธ๊ณ : ์ด๋ ์ ์ก ์ฑ๊ณต ์ฌ๋ถ๋ ์คํจ ์ฌ๋ถ์ ๋ํ ์ ๋ณด๊ฐ ์๋๋ผ, ํธ์ถ ๋ฐ ์ ์ก ์์ ์ ๊ฒฐ๊ณผ์ ๋ํ ์ ๋ณด๋ง ํฌํจ๋ฉ๋๋ค.
[Rpc]
public RpcInvokeInfo RpcFoo() {
// RPC ์์
์ํ
return default;
}
public override void FixedUpdateNetwork() {
var info = RpcFoo();
Debug.Log(info);
}
๋์ ์ง์ RPC
ํน์ ํ๋ ์ด์ด ๊ธฐ๊ธฐ์์๋ง ์คํ๋ RPC๋ฅผ ์ง์ ํ๋ ค๋ฉด ๋์ ์ง์ RPC๋ฅผ ์ฌ์ฉ
- ์ธ์คํด์ค RPC์ ์ ์ RPC ๋ชจ๋ PlayerRef ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ๊ณ [RpcTarget] ์์ฑ์ ์ ์ฉํ์ฌ ๋์ ์ง์ RPC๋ก ๋ณํ
- ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ ํ ์ฑํ ๊ณผ ๊ฐ์ด ๋ฉ์์ง๊ฐ ํน์ ํ์ ํ๋ ์ด์ด์๊ฒ๋ง ์ ๋ฌ๋๋๋ก ํ๋ ๊ฒฝ์ฐ
์ฐธ๊ณ : [RpcTarget] ๋งค๊ฐ๋ณ์์ PlayerRef.None์ ์ ๋ฌํ๋ฉด ์๋ฒ๋ฅผ ๋์์ผ๋ก ํฉ๋๋ค!
[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public void Rpc_TargetedInstanceMessage([RpcTarget] PlayerRef player, string message) {}
[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public static void Rpc_MyTargetedStaticMessage(NetworkRunner runner, [RpcTarget] PlayerRef player, string message) {}
์ค์: ๋ฉ์๋ ์ ์ธ ๋ด์์ ์ฌ์ฉํ๋ [RpcTarget] ์์ฑ์ ๋ฉ์๋ ์ ์ธ ์์ ์๋ [Rpc] ์์ฑ์ RpcTargets ๋งค๊ฐ๋ณ์์ ๋ค๋ฆ ๋๋ค.