- 개요
NetCode for GameObjects는 유니티에서 멀티플레이어 게임 개발을 지원하는 공식 네트워킹 프레임워크이다
언리얼 엔진의 Replication처럼 게임을 구성하는 여러 정보들을 동기화하는 목적으로 사용한다
- 사용 절차
1) 기본 세팅

패키지 매니저를 통해 NetCode for GameObjects 패키지를 설치한다

빈 게임 오브젝트를 생성하고 NetworkManager 컴포넌트를 추가한다
해당 컴포넌트를 사용하여 멀티 플레이와 관련된 대부분을 처리한다
주의해야 하는 점은 해당 컴포넌트는 1개만 존재해야 한다는 점이다

NetworkManager 컴포넌트의 주의사항에서 확인할 수 있듯이 의존 관계의 Multiplayer Tools 패키지도 설치한다

Network Transport 설정은 클라이언트와 서버 간에 교환되는 패킷을
어떤 방식으로 주고받을지 결정하는 전송 네트워크를 설정한다
프로젝트에서는 "Unity Transport"를 선택하였다
2) 플레이어 세팅

플레이어로 사용할 게임 오브젝트에 NetworkObject 컴포넌트를 추가한다
컴포넌트가 추가된 해당 오브젝트를 프리팹으로 전환한다

NetworkManager 오브젝트의 Default Player Prefab 속성에 위에서 생성한 프리팹을 추가한다
위와 같이 설정하면 플레이어가 네트워크에 연결되면 자동으로 해당 프리팹의 인스턴스를 생성한다
단, 해당 설정은 게임의 구성에 따라 설정하지 않아도 된다

스크립트를 작업한 뒤에 테스트를 목적으로 NetworkManager 컴포넌트는 3개의 버튼을 제공한다
- Start Host 버튼 : DedicatedServer로 실행
- Start Server 버튼 : ListenServer로 실행
- Start Client 버튼 : 클라이언트로 실행
3) 세 개의 버튼 테스트 - 데디케이트 서버 / 리슨 서버 / 클라이언트
public class NetworkManagerUI : MonoBehaviour
{
[SerializeField]
private Button serverBtn;
[SerializeField]
private Button hostBtn;
[SerializeField]
private Button clientBtn;
private void Awake()
{
serverBtn.onClick.AddListener(() => {
NetworkManager.Singleton.StartServer();
});
hostBtn.onClick.AddListener(() => {
NetworkManager.Singleton.StartHost();
});
clientBtn.onClick.AddListener(() => {
NetworkManager.Singleton.StartClient();
});
}
}
위와 같이 테스트를 위한 UI 클래스를 추가한다
3개의 버튼에 콜백 람다 함수를 바인드하여 데디케이트 서버 / 리슨 서버 / 클라이언트를 실행한다

이후 Network Manager 컴포넌트의 Log Level 속성을 Developer로 변경하여
가장 많은 정보를 포함하고 있는 로그를 출력하도록 설정한다

위와 같이 구성한 후에 에디터에서 리슨 서버를 실행하고, 빌드 파일에서 클라이언트를 실행하였다

Player.Log 파일에서 위와 같이 서버 - 클라이언트간에 연결이 이뤄진 것을 확인할 수 있다
4) 사용자의 입력 테스트

플레이어의 프리팹에 Network Transform 컴포넌트를 추가한다
해당 컴포넌트는 오브젝트의 트랜스폼 값의 상태를 탐지하고 변경된다면
변경 상태를 Authority를 가진 주체를 통해 브로드캐스트하는 용도로 사용한다
또, 트랜스폼의 변경은 보간을 통해 부드럽게 처리된다
public class PlayerNetwork : MonoBehaviour
{
private void Update()
{
Vector3 moveDir = new Vector3(0, 0, 0);
if (Input.GetKey(KeyCode.W)) moveDir.z = +1f;
if (Input.GetKey(KeyCode.S)) moveDir.z = -1f;
if (Input.GetKey(KeyCode.A)) moveDir.x = -1f;
if (Input.GetKey(KeyCode.D)) moveDir.x = +1f;
float moveSpeed = 3f;
transform.position += moveDir * moveSpeed * Time.deltaTime;
}
}
위와 같이 코드를 구성하여 W / A / S / D 입력에 따라 캐릭터를 이동시킬 수 있도록 설정한다

빌드된 2개의 exe 파일을 실행하여 결과를 확인한다
좌측은 리슨 서버로서 동작하고, 우측은 클라이언트로 동작한다
입력 결과를 확인해보면 리슨 서버의 입력은 잘 이루어지지만, 클라이언트의 입력은 처리되지 않고 있다
또, 리슨 서버에서의 입력이 클라이언트에서도 동일하게 적용되는 것을 확인할 수 있다
5) 사용자의 입력 테스트 - 문제해결

4)와 같은 문제는 씬에 생성된 리슨 서버와 클라이언트를 포함한 모든 플레이어 객체에서 스크립트가 동시에 실행되어,
하나의 입력으로 두 플레이어 객체가 함께 움직이게 되어 발생한다
따라서 코드를 위와 같이 수정한다
- MonoBehaviour가 아닌, NetworkBehaviour를 상속받도록 수정
- IsOwner 멤버변수를 사용하여 로컬의 플레이어인지 확인

이후 빌드 결과를 실행해보면 서버와 클라이언트의 입력이 서로 분리되어 처리되는 것을 확인할 수 있다
하지만 클라이언트에서 여전히 입력이 처리되지 않는 것을 확인할 수 있다
이런 문제는 Netcode for GameObjects의 기본 설정에서 클라이언트에 의한 게임 수정을 진행하지 않기 때문이다
'유니티 엔진 > 유니티 엔진의 구성' 카테고리의 다른 글
| 유니티 엔진의 구성 - 48) Game Override (0) | 2026.06.12 |
|---|---|
| 유니티 엔진의 구성 - 47) Remote Config (0) | 2026.06.10 |
| 유니티 엔진의 구성 - 46) 유니티 인증(Unity Authentication) (0) | 2026.06.01 |
| 유니티 엔진의 구성 - 45) 빌드 사이즈 리포트 (0) | 2026.05.27 |
| 유니티 엔진의 구성 - 44) 해상도 최적화 (0) | 2026.05.19 |