상태 동기화(State Synchronization)
플레이어 오브젝트

원격 액션(Remote Action)

네트워크 시스템에는 네트워크를 통해 동작을 수행하는 방법이 준비되어 있습니다. 이런 동작들의 유형에는 원격 프로 시저 호출(RPC)이라는 것이 있습니다. 네트워크 시스템의 RPC에는 두 종류가 있으며, 그 중 하나는 우선 명령(Command)입니다. 이것은 클라이언트에서 호출되어 서버에서 실행하는 것입니다. 다른 하나인 ClientRpc는 서버에서 호출되어 클라이언트에서 실행하는 것입니다.

아래의 다이어그램은 원격 동작의 흐름을 보여줍니다:

명령(Command)

명령(Command)은 클라이언트의 플레이어 오브젝트에서 서버의 플레이어 오브젝트로 보내는 것입니다. 보안 상의 이유로, 명령은 자신의 플레이어 오브젝트에서만 보낼 수 있습니다. 따라서 당신은 다른 플레이어를 조작할 수 없습니다. 함수를 명령으로 만들기 위해서는, 사용자 정의 속성 [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);
        }

    }
}

명령을 보내는 것이 클라이언트에서 매 프레임 실행된다는 점에 주의하십시오! 이 영향으로 많은 네트워크 장애가 발생할 수 있습니다.

기본적으로, 명령은 채널 0으로 전송됩니다.- 채널 0은 기본적으로 사용하는 신뢰성 높은 채널입니다. 따라서 일반적으로 모든 명령은 확실하게 서버로 전송됩니다. 채널은 [Command] 사용자 정의 특성의 “Channel” 파라미터에서 변경할 수 있습니다. 파라미터는 integer이며, 채널 번호를 나타냅니다.

채널 1은 기본적으로는 신뢰할 수 없는 채널로 설정되어 있습니다. 사용하려면 다음과 같이 Command 속성의 파라미터값을 1로 설정하십시오:

    [Command(channel=1)]

Unity 5.2 릴리스로 시작하는 경우, 클라이언트 권한을 가지는 논-플레이어 오브젝트로부터 명령을 보내는 것이 가능합니다. 이 오브젝트는 NetworkServer.SpawnWithClientAuthority로 스폰되어졌거나 NetworkIdentity.AssignClientAuthority로 설정된 권한을 가집니다. 이 오브젝트로부터의 명령은 클라이언트의 연관된 플레이어 오브젝트에서가 아닌 해당 오브젝트의 서버 인스턴스 상에서 실행됩니다.

ClientRpc 호출

ClientRpc 호출은 서버의 오브젝트에서 클라이언트 오브젝트로 전송됩니다. 이 호출은 NetworkIdentity를 갖는 스폰된 어떠한 서버 오브젝트로부터 전송될 수 있습니다. 서버에는 우선 순위가 있기 때문에, ClientRpc를 전송하는 서버 오브젝트에 보안 문제점은 없습니다. 함수를 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를 가지는 호스트로서 게임을 실행하는 경우, ClientRpc 호출은 LocalClient 상에서 실행됩니다. - 비록 동일한 서버로서 동일한 프로세스에 존재하는 경우에도 서버를 통해 하고 있는 것처럼 처리됩니다. 따라서 LocalClient와 RemoteClient의 행동은 ClientRpc 호출에 대해 동일합니다.

원격 액션에서의 인수

명령이나 ClientRpc 호출로 넘겨진 인수들은 직렬화되고 네트워크를 통해 전송됩니다. 이러한 인수들은 다음과 같은 것들이 될 수 있습니다:

  • basic types (byte, int, float, string, UInt64, etc)
  • arrays of basic types
  • structs containing allowable types
  • built-in unity math types (Vector3, Quaternion, etc)
  • NetworkIdentity
  • NetworkInstanceId
  • NetworkHash128
  • GameObject with a NetworkIdentity component attached

원격 액션으로의 인수들은 스크립트 인스턴스나 Transform와 같은 GameObject의 서브컴포넌트일 수 없습니다. 네트워크 상에서 직렬화될 수 없는 다른 타입들이 될 수 없습니다.

상태 동기화(State Synchronization)
플레이어 오브젝트