This document is about: FUSION 1
SWITCH TO

수정중인 페이지 입니다.

Remote Procedure Calls

소개

간단히 RPC라고 하는 원격 프로시저 호출은 정확한 게임 이벤트를 공유하는 데 이상적입니다. 이와 대조적으로 입력 구조체 및 [Networked] 속성은 지속적으로 변경되는 네트워크 클라이언트 간에 상태를 공유하는 데 필요한 솔루션입니다.

예를 들어 플레이어가 인벤토리의 특정 키를 사용하여 잠긴 문을 여는 등 입력 권한이 없는 개체와 드물지만 복잡한 상호 작용을 수행하려고 할 때입니다. 추가 필드를 입력의 일부로 포함하면 기술적으로 작업을 수행할 수 있지만, 입력 구조체가 혼란스럽고 다루기 어렵게 됩니다. 또한, 입력 구조체는 신뢰할 수 없는 메시지로 전송됩니다. 즉, 패킷이 손실될 수 있습니다. 이는 지속적인 입력(예: 캐릭터 이동)이 필요한 경우 거의 눈에 띄지 않지만 플레이어가 보장받을 것으로 예상되는 일회성 동작에 영향을 미칠 경우 플레이어 경험에 해로울 수 있습니다. 이러한 상황에서는 원격 프로시저 호출이 가장 좋습니다.

또한 입력 구조체는 신뢰할 수 없는 메시지로 전송됩니다. 즉, 패킷이 손실될 수 있습니다. 이것은 연속적인 입력(예: 캐릭터 이동)이 필요한 경우에는 거의 눈에 띄지 않지만, 이것이 플레이어가 보장받을 것으로 예상되는 단일 일회성 액션에 영향을 미칠 때 플레이어 경험에 해로울 수 있습니다. 이 경우 원격 프로시저 호출이 가장 좋은 방법입니다.

설정

Fusion은 간단하지만 강력한 RPC 용 구문을 가지고 있습니다. 실제로 말하는 RPC에는 세 가지 유형이 있습니다.

  1. 인스턴스 RPC
  2. 정적 RPC 및
  3. 대상 RPC.

이러한 유형 각각은 다음 섹션에서 설명됩니다.

인스턴스 RPC

NetworkBehaviourNetworkBehaviour에 RPC를 정의하려면 다음 단계를 수행하세요.

  1. 리턴 타입이 void 또는 RpcInvokeInfo 인 일반적인 CSharp 메소드를 선업합니다(아래에 문서화되어 있음)
  2. 메소드 이름의 프리- 또는 포스트픽스을 "RPC"로 지정합니다 (대소문자 구별)
  3. 메소드 선언 앞에 [Rpc] 속성을 추가합니다
  4. RPC가 호출될 수 있는 위치와 실행되는 위치를 제어하기 위해 RpcSourcesRpcTargets 매개 변수를 구성합니다.

C#

[Rpc(source: RpcSources.InputAuthority, target: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color){
    playerName = name;
    playerColor = color;
}

노트: RPC는 메소드 이름에 "rpc" 프리 또는 프리픽스가 있어야 합니다(대소문자 구분 없음).

정적 RPC

정적 RPC는 약간 다른 규칙을 갖고 있습니다:

  • RpcSourcesRpcTargets 파라미터를 무시하고
  • 메소드의 첫 번째 매개 변수는 NetworkRunner여야 합니다.
  • 콜백 리시버가 특정 NetworkObject에 바인딩되어 있지 않기 때문에 (NetworkBehaviour만이 아니라) 모든 SimulationBehaviour에서 구현할 수 있습니다.

소스 및 대상 필터가 없기 때문에 임의 클라이언트에서 정적 RPC를 호출할 수 있으며 모든 클라이언트로 전송됩니다. 여전히 RPC를 특정 PlayerRef("Targeted RPC" 참조)로 대상화하여 호출을 수신할 사람을 제어할 수 있습니다.

C#

[Rpc]
public static void Rpc_MyStaticRpc(NetworkRunner runner, int a) { }

RPC 속성 파라미터

소스 및 타겟

RpcSourcesRpcTargets는 필터입니다. RpcSources는 RPC를 전송할 수 있는 피어를 정의하는 반면, RpcTargets는 피어가 실행되는 피어를 정의합니다.

  • All: 전송할 수 있음 / 세션 내의 모든 피어에 의해서 실행됨(서버 포함).
  • Proxies: 전송할 수 있음 / 객체에 대하여 입력 권한 또는 상태 권한을 갖고 있지 않는 피어에 의해서 실행됨.
  • InputAuthority: 전송할 수 있음 / 객체에 대한 입력 권한이 있는 피어에 의해서 실행됨
  • StateAuthority: 전송할 수 있음 / 객체에 대한 상태 권한이 있는 피어에 의해서 실행됨.

중요: RPC에는 명시적 상태가 없습니다. RpcTargets.All로 설정하면 늦게 가입하는 클라이언트와 연결을 끊었다 다시 연결하는 클라이언트로 정보를 전달하지 않습니다. 따라서 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 속성 파라미터

RpcSourcesRpcTargets 속성 외에도 [Rpc] 속성은 몇 가지 선택적 파라미터를 제공합니다.

  • Channel (기본값 Reliable): 전송상에서 RPC가 없어질 수 있는 경우 Unreliable로 설정
  • InvokeLocal (기본값 true): RPC가 로컬 클라이언트에서 호출되지 않아야 하는 경우 false로 설정.
  • InvokeResim (기본값 false): 재시뮬레이션을 하는 동안 호출되지 않아야 하는 경우 true로 설정
  • TickAligned (기본값 true): 수신측이 에서 보낸 틱 이후까지 RPC 실행을 지연시키지 않으려면 false로 설정합니다.

C#

[Rpc (RpcSources.All, RpcTargets.All, InvokeLocal = true, InvokeResim = true, TickAligned = false )]
void RpcStartBoost(){
    m_BoostAnim.StartBoostAnimation();
}

RPC 메소드 파라미터

허용된 데이터 파라미터

  • 원시 타입
    • byte, sbyte
    • Int16, Int32, Int64
    • UInt16, UInt32, UInt64
    • float
    • double
    • float
    • double
  • 유니티 구조체 타입 (ILWeaver.cs에서 정의)
    • Vector2, Vector3, Vector4
    • Quaternion
    • Matrix4x4
    • Vector2Int, Vector3Int
    • BoundingSphere
    • Bounds
    • Rect
    • BoundsInt
    • RectInt
    • Color, Color32
  • System.Guid
  • 사용자 정의 INetworkStructs
  • Fusion 정의 INetworkStructs
    • NetworkString<IFixedStorage>
    • NetworkBool
    • Ptr
    • Angle
    • BitSet64, BitSet128, BitSet192, BitSet256
    • PlayerRefSet
    • NetworkId
    • NetworkButtons
    • NetworkRNG
    • NetworkObjectGuid
    • NetworkPrefabRef
    • NetworkObjectHeader
    • NetworkPrefabId
    • SceneRef
    • TickTimer
    • IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)
  • Fusion 타입
    • NetworkObject (NetworkId로 직렬화)
    • NetworkBehaviour (NetworkIdNetworkBehaviour 인덱스로 직렬화)
    • PlayerRef (PlayerRef.PlayerId로 직렬화)
  • Strings
  • 위에서 언급된 모든 타입의 배열

RpcInfo

RPC 메소드 선언RpcInfo 타입의 선택적인 파라미터를 받을 수 있습니다. 이렇게 하면 RPC에 대한 추가 정보를 읽을 수 있습니다.

  • Tick: 어떤 곳에서 틱이 전송되었는지.
  • Source: 어떤 플레이어(PlayerRef)가 보냈는지.
  • Channel: Unreliable 또는 Reliable RPC로 보냈는지 여부.
  • IsInvokeLocal: 이 RPC를 원래 호출한 로컬 플레이어인지의 여부.

C#

[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로 선언됩니다.

서버 vs 호스트 소스

ServerMode에서 Fusion을 사용할 경우 서버에서 보낸 RPC에 포함된 RpcInfo.Source는 서버가 플레이어가 아니기 때문에 PlayerRef.None으로 설정됩니다.

그러나 HostMode에서 Fusion을 사용하는 경우 호스트-클라이언트는 서버와 플레이어를 모두 실행합니다. 기본적으로 호스트가 보낸 모든 RPC는 서버와 동일하게 작동하며 RpcInfo.SourcePlayerRef.None으로 설정합니다. 호스트의 로컬 PlayerRef를 대신 포함하려면 HostMode 특성을 RpcHostMode.SourceIsHostPlayer로 설정해야 합니다.

HostMode는 다음 두 가지 모드 중 하나로 설정할 수 있습니다:

  • RpcHostMode.SourceIsServer (기본값): RpcInfo.SourcePlayerRef.None으로 설정됩니다.
  • RpcHostMode.SourceIsHostPlayer: Fusion이 HostMode에서 실행줄일 때 RpcInfo.Source가 로컬 PlayerRef로 설정됩니다.

호스트의 PlayerRefRpcSource.Info에 포함하기 위해서는 이전 코드가 다음과 같이 변경되어야 합니다:

C#

[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 메소드는 선택적으로 RpcInvokeInfo를 리턴 값으로 정의할 수 있습니다. RPC 메소드가 호출되면 RpcInvokeInfo 리턴 값에 RPC 호출 및 전송 작업에 대한 정보가 포함됩니다.

  • LocalInvokeResult: RpcLocalInvokeResult 열거혈 값은 로컬 호출 작업의 성공 또는 실패 원인을 나타냅니다.
  • SendCullResult: RpcSendCullResult 열거형 값은 원격 피어에 대한 RPC 호출의 성공 또는 실패 원인을 나타냅니다.
  • SendResult: RpcSendResult 구조체에는 RPC 전송 작업에 대한 메타 정보가 들어 있습니다.
    • Result: RpcSendMessageResult 이 RPC 메시지 보내기 작업에 대한 결과 플래그입니다.
    • MessageSize: RPC 패키지 크기.
    • Receivers: 이 RPC 작업의 리시버로 포함된 PlayerRef의 컬렉션
    • CulledReceivers: 이 RPC 전송 작업에서 리시버로 제외되고 도태된 PlayerRef의 모음입니다.

노트: 이 정보는 전송 성공 또는 실패에 대한 정보가 아니라 호출전송 작업의 결과일 뿐입니다.

C#

[Rpc]
public RpcInvokeInfo RpcFoo() {
  // RPC action
  return default;
}
 
public override void FixedUpdateNetwork() {
  var info = RpcFoo();
  Debug.Log(info);
}

대상 Rpc

RPC가 특정 플레이어의 컴퓨터에서 단독으로 실행되어야 하는 경우, 이른바 대상 RPC가 사용됩니다. 인스턴스 RPC와 정적 RPC는 모두 [RpcTarget] 속성 앞에 있는 PlayerRef 매개 변수를 추가하여 대상 RPC로 전환할 수 있습니다. 일반적인 사용 사례는 메시지가 소속 팀의 특정 선수에게만 제공되는 팀 채팅입니다.

노트: [RpcTarget] 파라미터로 PlayerRef.None로 전달하는 것은 서버가 대성입니다!

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public void Rpc_TargetedInstanceMessage([RpcTarget] PlayerRef player, string message){}

또는

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public static void Rpc_MyTargetedStaticMessage(NetworkRunner runner, [RpcTarget] PlayerRef player, string message) { };

중요: 메소드 선언 에서 사용된 [RpcTarget] 속성은 메소드 선언 에 위치한 [Rpc] 속성 내부의 RpcTargets다릅니다.

Back to top