글 들어가기에 앞서..

Netcode 공부하게 된 계기는 졸업작품 만드는거 관련해서 무슨 게임을 만들까

의논을 하던 도중 신(god) 팀장이 멀티게임을 만들어보는게 어떨까 하는 의견에

멀티 게임을 만들게 되어서 Netcode를 공부하게 되었음.


Netcode란?

일단 Netcode는 쉽게 말해서 유니티 자체 라이브러리에서 지원해 주는

멀티게임 개발 도구? 라고 볼 수 있다.


제 1장 네트워크 기본 공부

이번 공부에서 배운 방식은 총 3가지이다.


먼저 첫번째 방식은 Client Host 방식이다.

 

이 방식은 별도의 서버 없이 동일 네트워크 상에서만 통신을 하는 방식이다.

장점. 돈이 들지 않는다

단점. 같은 네트워크 상에서만 멀티가 가능하다.


위에서 나온 Client Host 방식에 전세계 사람들과 멀티가 가능하도록 중간에 중계소를 두는 방법이

두번째 방법이다.

장점. 작은 규모의 서버 운영에 편리함

단점. 큰 규모의 서버를 돌리기엔 서버가 너무 작음


세번째 방식은 아에 서버를 돌리면서 그 서버에 클라이언트 들이 접속하는 방식이다.

장점. 성능, 균형, 보안 등 모든 방면에서 좋음

단점. 매우 많은 돈이 필요함, 서버 구축이 어려움


이렇게 간단하게 만들어볼 게임의 네트워크 방식에 대해서 알아보았고

이제부터는 실질적으로 Netcode를 유니티에서 어떤 식으로 사용할 수 있는지에 대해서 알아보도록 하겠음

 

위 이미지에서 볼 수 있듯이 Netcode 패키지를 다운하게 되면 다음과 같은 컴포넌트를 사용할 수 있게 된다

저 네트워크 매니저는 실질적인 서버의 호스트와 클라이언트를 구별하여 서버를 구축할 수 있도록 되어있다 

(유니티 기본제공, 싱글톤으로도 만들어짐)

 

상단의 Player Prefab 칸에 프리팹을 등록하게 될 시 클라이언트가 서버에 접속할 때

자동적으로 프리팹이 생성되도록 해준다.

 

저렇게 서버를 구축을 하게 되면 플레이어가 움직이고 상호작용 하는 것들이 바로 바로 전송이 될까?

 

그건 아니다.

 

이동과 회전 그리고 크기를 동기화 하기 위해서는 서버에서 사용할 오브젝트 내에 

이와같은 컴포넌트를 추가해 주어야 동기화 할 수 있게된다.

 

그런데 이 편리해 보이는 Network Transform도 약간의 단점이 있다

그건 바로 서버만 움직일 수 있다는 것이다.

 

모든 처리를 서버가 하게 되면 클라이언트의 입력 후 전달 되는 레이턴시가 

 이처럼 길어지니 유저들에게 많은 불편을 안겨줄 수 있다.

 

따라서 이동은 클라이언트가 제어를 할 수 있도록 만들어야 함으로

 

Network Transform을 수정하여 클라이언트가 직접 이동을 제어할 수 있도록 만들 수 있다.

 

using Unity.Netcode.Components;

public class ClientTransform : NetworkTransform
{
    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();
        CanCommitToTransform = IsOwner; //소유자는 변경이 가능하게
    }

    protected override bool OnIsServerAuthoritative()
    {
        //서버인증을 false로 놓고
        return false;
    }

    protected override void Update()
    {
        CanCommitToTransform = IsOwner;
        base.Update();

        //이건 NetworkTransform안에 있는 거다. 정확히는 NetworkBehaviour라는 것 밑에
        //얘는 NetworkObject에 붙은 NetworkManager를 가져오는거 (이게 어짜피 네트워크 싱글톤임)
        //구현부를 읽어보면 차후 여러개의 네트워크 매니저 구동시에 해당 오브젝트를 소유한 네트워크 매니저를 리턴하도록 만들 예정
        if (NetworkManager != null)
        {
            //클라이언트로서 연결되어있거나 서버로서 리스닝을 하고 있는 중이라면 
            if (NetworkManager.IsConnectedClient || NetworkManager.IsListening)
            {
                if (CanCommitToTransform)
                {
                    //그럼 서버로 자신의 transform과 현재시간으로 동기화를 시도한다. 
                    //시간을 주면 interpolate가 가능하다.

                    TryCommitTransformToServer(transform, NetworkManager.LocalTime.Time);
                }
            }
        }
    }
}

오늘은 1일차니 간단하게 게임을 만들 때 사용할 수 있는 네트워크의 간단한 종류와

Netcode에서 제공해주는 Network Manager, Network Transform에 대해서 알아보았다