🔍 학습 동기
멀티플레이 게임 구조에 대해 궁금증이 생기며, Unity 기반에서 네트워크 동기화, 서버 권한 구조, 치트 방지 기법 등을 체계적으로 정리하고자 Photon PUN 2를 주제로 학습을 진행했다.
📚 학습 내용 정리
✅ 1. Photon의 기본 구조
- PhotonNetwork.ConnectUsingSettings()을 통해 Photon Cloud 서버에 접속하고, 이후 룸에 참가하거나 생성한다.
- PhotonNetwork.Instantiate()는 Resources 폴더 내에 존재하며 PhotonView가 붙은 프리팹만 네트워크로 생성 가능하다.
- PhotonView.IsMine을 통해 해당 오브젝트가 내 클라이언트의 소유인지 판단하고, 조작은 소유자만 가능하도록 제한해야 한다.
✅ 2. 동기화 기법: OnPhotonSerializeView
- 실시간으로 위치, 체력, 속도 등의 값을 네트워크에 전파할 수 있다.
- stream.IsWriting 시에는 값을 보내고, IsReading 시에는 받는다.
- ReliableDeltaCompressed를 사용하면 변경된 값만 전송하므로 효율적이며, UnreliableOnChange는 조건에 따라 값이 무시될 수 있다.
- 핵심 개념: "보낸다고 전송되는 게 아니라, PhotonView 설정과 실제 값 변화가 전송의 조건이 됨."
✅ 3. 애니메이션 동기화의 오해
- 동일한 애니메이션을 각 클라이언트에서 실행해도, 시작 시점이 다르기 때문에 약간의 프레임 차이가 발생할 수 있음.
- 해결법은 RPC를 통해 정확한 시점에 동기화하거나, Animator parameters를 OnPhotonSerializeView로 전파하는 방식이 있다.
✅ 4. RaiseEvent vs RPC
항목RPCRaiseEvent
| 대상 지정 |
특정 대상 호출 (예: 이펙트 실행) |
모든 클라이언트 브로드캐스트 |
| 사용 예시 |
킬 애니메이션 실행 |
유저가 죽었다는 게임 상태 알림 |
| 신뢰성 설정 |
자동으로 신뢰 전송 |
RaiseEventOptions를 통해 설정 필요 |
- RPC는 "행동 명령", RaiseEvent는 "게임 상태 동기화"에 더 적합
✅ 5. 클라이언트와 서버 역할 구분
- Photon PUN은 완전한 서버 권한 구조가 아니므로, 보안상 민감한 데이터(체력, 아이템 사용 등)는 클라이언트가 직접 조작하면 안 됨.
- 이를 방지하기 위해:
- 마스터 클라이언트가 모든 상태를 검증 및 전파
- 또는 별도 Node.js API 서버를 통해 DB 기반 검증 수행
✅ 6. 치트 방지 전략
- 이동속도나 체력처럼 치트 위험이 있는 항목은 클라이언트 → 서버 요청 → 서버 판정의 흐름을 따라야 한다.
- 예시: 클라이언트가 “달리기 시작”을 요청 → 서버가 속도값을 설정하고 그 값을 전파
- 실시간 이동을 매 프레임 검증하는 것이 아니라, 3~5초 간격 또는 상태 변화 발생 시 샘플링 검사로 효율적 대응
✅ 7. 게임 구조 설계 인사이트
- 게임 내 일시적인 정보 (위치, 체력, 생존 여부 등)는 Photon 룸 내에서 관리
- 게임 외 지속적 정보 (레벨, 재화, 경험치, 스킨 등)는 Node.js + MySQL DB에서 관리
- 게임 종료 시 결과 요약을 API로 전송하여 보상을 처리
- Unity와 C# 기반 서버 구조는 코드 공유와 유지보수에 매우 유리
❓ 궁금했던 점과 해결
질문핵심 이해
| 내 클라이언트만 움직이는 이유는? |
PhotonView.IsMine이 false일 경우 입력 무시됨 |
| 체력값이 항상 0으로 나옴 |
OnPhotonSerializeView에서 값이 잘못 보내지거나, View 동기화 설정 누락 |
| RaiseEvent와 RPC의 용도 차이는? |
RPC는 특정 행동, RaiseEvent는 상태 브로드캐스트에 적합 |
| 클라가 체력 바꿔도 되나? |
❌ 절대 안 됨. 서버가 판정 후 전파해야 함 |
| 이동속도는 매 프레임 검증해야 하나? |
❌ 성능 저하. 대신 이상 징후 감지 로직으로 충분함 |
| 대규모 게임은 어떤 구조를 쓰나? |
수십만 동접 이상이면 C++ 기반 커스텀 서버가 필요 |
💭 느낀 점
이번 학습을 통해 Photon의 구조적 특성과 P2P에 가까운 네트워크 특성을 이해하게 되었다. 클라이언트가 주도하는 로직은 매우 위험하며, 서버가 판정을 내리는 구조로의 설계가 치트 방지와 데이터 신뢰성을 확보하는 핵심임을 깨달았다. 게임의 규모가 커질수록 구조를 단순히 "연결만 되면 된다"가 아닌, 보안과 동기화, 권한 분리를 고려한 네트워크 설계가 요구된다.