ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 네트워크(UNet)
    게임개발 2017. 6. 20. 16:04

    유니티 네트워크에 대해 공부하면서 별것 아니지만 소소한 내용들이 골머리를 앓게 했는데 그것에 대해 짧게 글을 써보려고 한다.

    해당 게시물은 내가 새롭게 공부하는 족족 지속적으로 변경될 수 있다.


    유니티 네트워크에서는 네트워크 모델을 크게 3가지로 구분짓고 있는데 각각 서버, 클라이언트, 호스트이다.

    서버는 그 이름에서도 알 수 있다시피 클라이언트로부터 네트워크 요청을 전송받아 특정 처리를 해주는 개체이다.

    클라이언트는 서버에 어떤 처리를 요청할 수 있는 개체이다.

    호스트는 특이하게도 서버와 클라이언트 둘 다의 역할을 수행한다.


    네트워크 커넥션은 일방적으로 클라이언트가 서버에 요청하는 과정을 가진다. 그러므로 서버는 하나이며 클라이언트는 다수이다. (1:N)

    서버를 통하지 않고 클라이언트끼리 통신이 가능하지 않냐고? 글쎄.. 그건 잘 모르겠다.


    유니티 네트워크를 사용하기 위해서는 알아야하는 개념이 몇가지 있다.

    서버와 클라이언트끼리 네트워크 통신을 하기 위해서는 우선 먼저 커넥션이 연결되어야 한다.



    또한 네트워크를 주고 받을 수 있는 특수한 객체 NetworkBehavior가 정상적으로 NetworkManager에 의해 정상적으로 Spawn되어 Valid한 networkId 값을 할당받은 상태여야 정상적인 통신이 이루어진다.

    유니티에서는 모든 리소스들이 게임 오브젝트라는 공통된 개체로 사용되기 때문에 게임 오브젝트내에서 어떤 메커니즘으로 통신이 이루어지는가를 먼저 파악해야 한다.

    게임 오브젝트는 일반적으로 MonoBehavior 클래스를 상속받는데 네트워크 통신을 위해서는 Mono가 아닌 NetworkBehavior 클래스를 상속 받야아 한다. NetworkBehavior는 MonoBehavior의 모든 특성을 다 가지고 있기 때문에 호환문제 없이 사용이 가능하다.


    NetworkBehavior를 상속받은 클래스는 여러가지 특수한 어트리뷰트([]로 표현되는 지시자)를 사용할 수 있는데 특히 통신에서 활용되는 [Command]와 [RpcClient] 어트리뷰트에 대해 알고 있어야 한다.


    단도직입적으로 NetworkBehavior 오브젝트(인스턴스화 된 클래스를 의미)끼리 통신을 하기 위해서는 Command 함수와 RpcClient 함수가 필요하다는 점을 알아야 한다. 


    Command 함수는 클라이언트 -> 서버로 요청하는 함수이고 RpcClient 함수는 서버 -> 클라이언트로 방송(Broadcasting)하는 함수이다.

    네이밍 정책이 있는데 Command 함수의 이름 앞에는 Cmd라는 약어가 들어가야하고 RpcClient 함수 이름 앞에는 Rpc라는 약어가 들어가야 한다.

    예를들면 ABC라는 이름의 통신하는 함수를 생성하고 싶을때 Command라면

    [Command]

    void CmdABC();

    이렇게

    RpcClient라면

    [RpcClient]

    void RpcABC();

    이렇게 설정해야 한다는 의미이다.


    특이점을 살펴보자

    1. Cmd 함수는 독특한 형태를 가지고 있는데 함수를 호출하는 부분은 클라이언트이지만 실질적으로 함수가 실행되는 부분은 클라이언트가 아닌 서버라는 점이다.

    2. Server에서는 Cmd 함수 호출이 불가능하고 Client에서는 Rpc 함수의 호출이 불가능하다.

    사실 이렇게만 들으면 별 다른게 없어보인다. 하지만 이 부분에 대해서 정확히 이해하지 않으면 다음단계로 넘어가는데 어려움이 생길 수 있다.


    테스트 케이스를 통해 Cmd와 Rpc 함수가 어떻게 동작하는지 확인해보겠다.

    class TestObj : NetworkBehavior

    {

    [Command] void CmdABC() {Debug.Log("이 로그는 서버에서 실행됩니다.")}

    [RpcClient] void RpcABC() {Debug.Log("이 로그는 클라이언트에서 실행됩니다.")}

    void Test() {CmdABC(); RpcABC();}

    }


    위와 같은 네트워크 객체가 있다고 했을때 TestObj.Test() 다음 함수를 실행시키면 서버와 클라이언트 모두 같은 결과가 나올까?

    그렇지 않다 

    Server에서는 "이 로그는 서버에서 실행됩니다." 로그만 뜨게 되고

    Client에서는 "이 로그는 클라이언트에서 실행됩니다." 로그만 뜨게 된다.

    이 점에 대해서 잘 알고 있어야 한다.

Designed by Tistory.