Version: 2019.4
언어: 한국어
액션 및 커뮤니케이션
네트워크 관리자 콜백

원격 액션

참고: UNet은 지원이 중단되었으며 향후 Unity에서 삭제될 예정입니다. 현재 새로운 시스템이 개발 중입니다. 자세한 내용과 다음 단계는 이 블로그 포스트FAQ를 참조하십시오.

네트워크 시스템은 네트워크 간 액션을 수행하는 방법이 있습니다. 이들 액션은 가끔 원격 프로시저 호출 (RPC)이라고 합니다. 네트워크 시스템에는 두 가지 타입의 RPC가 있습니다. 하나는 클라이언트에서 호출되어 서버에서 실행되는 커맨드이고, 다른 하나는 서버에서 호출되어 클라이언트에서 실행되는 ClientRpc 호출입니다.

아래 다이어그램은 원격 액션이 발생하는 방향을 보여줍니다.

커맨드

커맨드는 클라이언트에서의 플레이어 오브젝트에서 서버에서의 플레이어 오브젝트로 보내집니다. 커맨드는 사용자의 플레이어 오브젝트에서만 보낼 수 있으며 다른 플레이어의 오브젝트는 제어할 수 없습니다. 함수를 커맨드로 바꾸려면 [Command] 커스텀 속성과 “Cmd” 접두사를 추가해야 합니다. 이 함수는 이제 클라이언트가 호출하면 서버에서 실행됩니다. 인자는 모두 커맨드와 같이 서버로 전달됩니다.

커맨드 함수는 “Cmd” 접두사가 있어야 합니다. 이 접두사는 커맨드를 호출하는 코드를 나타냅니다. 이 함수는 특수 함수로 다른 노멀 함수와 같이 호출되지는 않습니다.

class Player : NetworkBehaviour
{

    public GameObject bulletPrefab;

    [Command]
    void CmdDoFire(float lifeTime)
    {
        GameObject bullet = (GameObject)Instantiate(
            bulletPrefab, 
            transform.position + transform.right,
            Quaternion.identity);
            
        var bullet2D = bullet.GetComponent<Rigidbody2D>();
        bullet2D.velocity = transform.right * bulletSpeed;
        Destroy(bullet, lifeTime);

        NetworkServer.Spawn(bullet);
    }

    void Update()
    {
        if (!isLocalPlayer)
            return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            CmdDoFire(3.0f);
        }

    }
}

매 프레임마다 클라이언트가 커맨드를 보내지 않도록 해야 합니다. 네트워크 트래픽이 과다하게 발생할 수 있습니다.

기본적으로 커맨드는 디폴트 신뢰 채널인 채널 제로를 통해 보내집니다. 따라서 기본적으로 모든 커맨드는 서버에 확실하게 전달됩니다. 채널은 [Command] 커스텀 속성의 “채널” 파라미터에서 커스터마이즈할 수 있습니다. 이 파라미터 값은 채널 번호를 나타내는 정수이어야 합니다.

채널 1은 디폴트 비신뢰 채널로 설정되어 있으므로 이 채널을 사용하려면 아래와 같이 커맨드 특성 파라미터에서 값을 1로 설정하면 됩니다.

    [Command(channel=1)]

Unity 릴리스 5.2 이후 버전부터 플레이어가 없는 오브젝트(클라이언트 권한 있음)에서 커맨드를 보낼 수 있습니다. 이러한 오브젝트는 NetworkServer.SpawnWithClientAuthority를 통해 스폰되거나 NetworkIdentity.AssignClientAuthority를 통해 권한을 설정한 상태여야 합니다. 이러한 오브젝트에서 전송한 커맨드는 오브젝트의 서버 인스턴스에서 실행되고, 클라이언트에서의 해당 플레이어 오브젝트에서 실행되지 않습니다.

ClientRpc 호출

ClientRpc 호출은 서버에서의 오브젝트에서 클라이언트에서의 오브젝트로 보내집니다. NetworkIdentity를 포함하여 생성된 모든 서버 오브젝트가 이 호출을 보낼 수 있습니다. 서버는 권한을 가지고 있으므로, 서버 오브젝트가 호출을 보내는 것과 관련하여 보안 문제는 없습니다. 함수를 ClientRpc 호출로 만드려면, [ClientRpc] 커스텀 특성과 “Rpc” 접두사를 추가해야 합니다. 이 함수는 이제 서버에서 호출되면 클라이언트에서 실행됩니다. 인자는 모두 ClientRpc 호출과 같이 서버로 전달됩니다.

ClientRpc 함수는 “Rpc” 접두사가 있어야 합니다. 접두사는 메서드를 호출하는 코드를 나타냅니다. 함수는 특수 함수로 다른 노멀 함수와 같이 호출되지는 않습니다.

class Player : NetworkBehaviour
{

    [SyncVar]
    int health;

    [ClientRpc]
    void RpcDamage(int amount)
    {
        Debug.Log("Took damage:" + amount);
    }

    public void TakeDamage(int amount)
    {
        if (!isServer)
            return;

        health -= amount;
        RpcDamage(amount);
    }
}

LocalClient로 게임을 호스팅하는 경우, 서버에서 같은 과정을 거치더라도 LocalClient에서 ClientRpc 호출이 발생합니다. 따라서 LocalClients와 RemoteClients 둘 다 ClientRpc 호출에 대해서는 동일하게 동작합니다.

원격 액션의 인자

커맨드와 ClientRpc 호출로 전달되는 인자는 직렬화되어 네트워크로 보내집니다. 인자는 다음 중 하나입니다.

  • 기본 타입(byte, int, float, string, UInt64 등)
  • 기본 타입 배열
  • 허용 가능 타입을 포함하는 구조체
  • 빌트인 Unity 수학 타입(Vector3, Quaternion 등)
  • NetworkIdentity
  • NetworkInstanceId
  • NetworkHash128
  • NetworkIdentity 컴포넌트가 부착된 게임 오브젝트

원격 액션으로 전달되는 인자는 스크립트 인스턴스나 트랜스폼과 같이 게임 오브젝트의 하위 요소여서는 안됩니다. 직렬화되어 네트워크로 보내질 수 없는 타입도 인자가 될 수 없습니다.

액션 및 커뮤니케이션
네트워크 관리자 콜백