🔍 IInputComponentData
https://docs.unity3d.com/Packages/com.unity.netcode@1.5/api/Unity.NetCode.IInputComponentData.html
Netcode for Entities (NFE)에서 클라이언트의 입력을 서버로 전송하기 위해 특별히 설계된 인터페이스
IInputComponentData
의 핵심 역할
1️⃣ 입력 데이터의 네트워크 동기화
- 클라이언트 → 서버로의 입력 전송을 최적화합니다.
- NFE는 이 인터페이스가 붙은 컴포넌트를 자동으로 직렬화/역직렬화합니다.
2️⃣ 예측(Prediction) 시스템 지원
- 클라이언트 측 예측과 서버 측 보정을 가능하게 합니다.
GhostPredictionSystemGroup
에서 특별 처리됩니다.
3️⃣ 입력 버퍼링
- 틱(tick) 기반으로 입력을 저장해 네트워크 지연 보정에 사용됩니다.
✍🏻예시 코드
using Unity.Entities; using Unity.NetCode; // 반드시 IInputComponentData를 상속해야 함 public struct NetcodePlayerInput : IInputComponentData { // 필드에 [GhostField] 속성을 추가해 직렬화 옵션 지정 [GhostField(Quantization = 100)] // 값 범위: -1.0 ~ 1.0 → -100 ~ 100으로 압축 public float MoveX; // 좌우 이동 입력 (-1: 왼쪽, 1: 오른쪽) [GhostField] public float MoveY; // 전후 이동 입력 [GhostField] public InputEvent Jump; // 점프 입력 (버튼 상태) // 현재 틱 정보 (NFE가 자동으로 주입) public uint Tick { get; set; } }
❓[GhostField(Quantization = 100)] 양자화를 사용하는 이유
Netcode for Entities (NFE)에서 네트워크 대역폭을 최적화하기 위해 사용되는 핵심 기능
1️⃣ 데이터 압축으로 대역폭 절감
- 원본 데이터:
float
(32비트) - 양자화 후:
short
(16비트) 등 작은 타입으로 변환
[GhostField(Quantization = 100)] public float MoveX; // -1.0 ~ 1.0 → -100 ~ 100 정수로 압축 // 1.75f → 175 (전송) : 수신 측에서 1.75f로 복원
2️⃣ 네트워크 지연 감소
작은 데이터 패킷으로 통신하여 전송 시간 단축하여 실시간 반응성 향상 (지연 시간 감소)
3️⃣ 작동 원리
원본 값 | 양자화 계수 | 송신 값 | 복원 값 | 오차 |
---|---|---|---|---|
0.73f | 100 | 73 | 0.73f | 0% |
1.28f | 100 | 128 | 1.28f | 0% |
0.123f | 100 | 12 | 0.12f | 2.4% |
- 적정 범위:
-1.0 ~ 1.0
(조이스틱 입력 등)Quantization = 100
→-100 ~ +100
(총 201단계)- 필요 비트:
⌈log₂(201)⌉ = 8비트
(1바이트)
- 정밀도 vs 효율 트레이드오프:
- 100: 0.01 단위 정밀도 (대부분의 게임 입력에 충분)
- 1000: 0.001 단위 (고정밀 필요 시) → 대역폭 2배 소모
4️⃣ 간단 적용 예시
// 캐릭터 이동 [GhostField(Quantization = 100)] public float Horizontal; // 좌우 이동 (-1.0 ~ 1.0) [GhostField(Quantization = 100)] public float Vertical; // 전후 이동 // 캐릭터 회전 [GhostField(Quantization = 32767)] // short.MaxValue public float RotationY; // 0 ~ 360도 → -32767 ~ 32767
5️⃣ 최적화 가이드
값 범위 | 권장 양자화 계수 | 비트 사용량 |
---|---|---|
-1.0 ~ 1.0 | 100 | 8비트 |
-10.0 ~ 10.0 | 10 | 8비트 |
0 ~ 360 (각도) | 32767 | 16비트 |
고정밀 물리 파라미터 | 10000+ | 16~32비트 |
6️⃣ 주의사항
- 오버플로우 방지
Quantization
값을 너무 크게 설정하면 정수 변환 시 오버플로우 발생 가능:
// 위험 예시 (float.MaxValue → 양자화 시 오류) [GhostField(Quantization = 1000000)] public float DangerValue;
- 정밀도 한계
0.005f
같은 미세한 값은Quantization=100
에서 반올림 오차 발생:
0.005f * 100 = 0.5f → 반올림 → 1 → 복원 시 0.01f (100% 오차)
- 에디터 디버깅
NetworkProtocol
로그에서 실제 전송 크기 확인:
// Unity 콘솔에 패킷 크기 출력 Debug.Log($"패킷 크기: {System.Runtime.InteropServices.Marshal.SizeOf(packet)}바이트");
7️⃣ 성능비교
// 양자화 미적용 (32비트 float) [GhostField] public float Uncompressed; // 4바이트 // 양자화 적용 (8비트 압축) [GhostField(Quantization = 100)] public float Compressed; // 1바이트 절감 효과: 75% 대역폭 감소 (4배 효율) 초당 60프레임 기준: 미적용: 60fps * 4B = 240B/s 적용: 60fps * 1B = 60B/s
IInputComponentData
와 IComponentData
의 차이점
특징 | IInputComponentData | IComponentData |
---|---|---|
자동 직렬화 | ⭕ 네트워크 전송 최적화 | ❌ 직접 구현 필요 |
예측 지원 | ⭕ PredictedGhost 와 연동 | ❌ 별도 시스템 필요 |
틱 동기화 | ⭕ Tick 프로퍼티 자동 관리 | ❌ 수동 처리 |
버퍼링 | ⭕ 입력 히스토리 유지 | ❌ 직접 구현 |