Let's Girin!

[Unity] DOTS - Netcode for Entities 본문

Unity

[Unity] DOTS - Netcode for Entities

window= 2026. 6. 27. 11:28

1. Netcode for Entities란?

Unity에서 제공하는 두 가지 주요 넷코드 솔루션 중 하나로, 특히 빠른 페이스의 경쟁 게임에 적합하다. 이는 권한 서버를 사용하며,클라이언트측 예측을 지원한다. 이러한 특성 덕분에 실시간 게임에서 발생할 수 있는 네트워크 지연을 최소화하고, 더욱 부드러운 게임플레이 경험을 제공한다.

 

 

2. Netcode for GameObject 와의 차이

  • Netcode for GameObjects는 주로 게임 오브젝트 기반의 네트워크 로직을 구현한다.
  • 반면, Netcode for Entities DOTS (Data-Oriented Technology Stack)와 통합되어, 엔티티 기반의 더 효율적인 네트워크 처리 방식을 제공한다.

 

 

3. 핵심 기능

🔹권한 서버

게임의 모든 시뮬레이션을 중앙에서 처리하며, 서버가 모든 게임 로직의 권한을 담당한다.

클라이언트는 단순히 입력을 서버에 전송하고, 서버는 이를 처리하여 결과를 클라이언트에 다시 전송한다.

이러한 방식은 부정 사용자의 악용을 방지하고, 게임 로직의 일관성을 유지하는 데 유리하다.

  • 클라이언트는 서버에 입력을 전송
  • 서버는 게임 상태를 갱신하고 새로운 스냅샷을 클라이언트에 전송
using Unity.NetCode;
using Unity.Networking.Transport;
using UnityEngine;
 
// 게임 시작 시 서버/클라이언트 월드를 자동으로 생성한다.
// 에디터에서는 서버+클라이언트를 동시에 실행하고, 빌드에서는 역할에 따라 분리된다.
public class GameBootstrap : ClientServerBootstrap
{
    public override bool Initialize(string defaultWorldName)
    {
        // 자동으로 서버/클라이언트 월드 생성.
        AutoConnectPort = 7979;
        return base.Initialize(defaultWorldName);
    }
}
 
// 서버에 연결 요청을 보내는 시스템.
[WorldSystemFilter(WorldSystemFilterFlags.ClientWorld)]
public partial class ConnectToServerSystem : SystemBase
{
    protected override void OnCreate()
    {
        // 서버 엔드포인트 설정 (로컬 테스트용).
        var endpoint = NetworkEndpoint.LoopbackIpv4.WithPort(7979);
 
        // 드라이버 싱글톤에서 연결 요청.
        var driver = SystemAPI.GetSingleton<NetworkStreamDriver>();
        driver.Connect(EntityManager, endpoint);
    }
 
    protected override void OnUpdate() { }
}

🔹클라이언트 예측

네트워크 지연으로 인해 클라이언트가 서버보다 늦은 상태를 수신하게 된다. 

이를 해결하기 위해 클라이언트 측 예측 기능을 사용한다. 

클라이언트는 수 밀리초 후의 상태를 예측하고, 서버와 일치하는지 비교하여 지연을 최소화한다.

  • 서버와 일치하는 예측을 통해 지연 없이 게임이 진행되는 느낌을 제공한다.
  • 클라이언트는 플레이어 캐릭터와 같은 중요한 요소에 대해 예측을 수행한다.
using Unity.Entities;
using Unity.NetCode;
using Unity.Mathematics;
using Unity.Transforms;
 
// Ghost 컴포넌트: 네트워크를 통해 동기화할 데이터를 정의한다.
// GhostField 어트리뷰트가 붙은 필드만 서버→클라이언트로 복제된다.
[GhostComponent(PrefabType = GhostPrefabType.AllPredicted)]
public struct PlayerData : IComponentData
{
    [GhostField] public float3 Position;
    [GhostField] public float  Speed;
    [GhostField] public int    Health;
}
 
// 예측 시스템: PredictedGhost 태그가 있는 엔티티만 처리한다.
// 클라이언트는 입력을 받는 즉시 이 시스템으로 결과를 예측하고, 서버 스냅샷이 도착하면 차이를 보정(Reconcile)한다.
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
public partial struct PlayerMoveSystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        float deltaTime = SystemAPI.Time.DeltaTime;
 
        foreach (var (input, playerData, localTransform)
            in SystemAPI.Query<
                RefRO<PlayerInput>,
                RefRW<PlayerData>,
                RefRW<LocalTransform>>()
            .WithAll<PredictedGhost>())
        {
            // 입력값으로 이동 방향 계산.
            float3 moveDir = new float3(input.ValueRO.Horizontal, 0f, input.ValueRO.Vertical);
 
            // 위치 업데이트 (클라이언트 즉시 반영 + 서버 동일 로직).
            localTransform.ValueRW.Position +=
                moveDir * playerData.ValueRO.Speed * deltaTime;
 
            playerData.ValueRW.Position = localTransform.ValueRO.Position;
        }
    }
}

 

4. Netcode for Entities의 장점

🔹확장성과 대역폭 최적화

Netcode for Entities는 Netcode for GameObjects보다 더 확장성이 뛰어나며, 대역폭을 효율적으로 최적화할 수 있는 기능을 제공한다.이는 더 많은 플레이어가 참여하는 게임에서 특히 중요한 요소이다.

🔹DOTS 및 엔티티 컴포넌트 시스템

DOTS 기반의 개발을 지원하며, 엔티티 컴포넌트 시스템(ECS)을 확용하여 높은 성능을 자랑한다. 이를 통해 수많은 동적 객체를 효율적으로 처리할 수 있다.

 

 

* Netcode for Entities는 빠른 페이스의 경쟁 게임에 적합한 넷코드 솔루션이다. 권한 서버와 클라이언트 측 예측을 활용하여 게임 내 지연을 최소화하고, 확장성과 대역폭 최적화를 통해 더욱 효율적으로 멀티플레이어 환경을 구현할 수 있다.

 

 


◈ 유니티 공식 문서를 참고하여 작성하였습니다◈

반응형