Git
레포지토리 주소 : https://github.com/kjinwoo12/UE5_MultiplayLibrary
기준 태그 : V1.0.1
본문
리그오브워치 개발 중에 멀티플레이 관련 코드를 작성하게 되었다. [리그오브워치개발일지] #12-2 멀티플레이 전용 게임모드 클래스 추가에 대한 추가 글이다.
개발 필요성
플레이어가 서버에 접속했을 때 클라이언트에서 함수가 실행되는 동안 GameState
와 PlayerState
가 유효하다는 보장이 없다. 클라이언트에서 GameState
또는 PlayerState
의 BeginPlay
가 호출되기 전에 다른 액터의 BeginPlay
또는 RPC 가 실행될 가능성이 있다는 뜻이다. 문제를 해결하기 위해서는 GameState
와 PlayerState
의 BeginPlay
가 호출된 시점을 알려서 원하는 기능이 실행될 시점을 뒤로 미뤄야 한다.
로컬 플레이어의 PlayerState
는 간단한 검사를 통해 클라이언트에서 유효성을 보장받지만, 다른 모든 플레이어의 PlayerState
가 유효한지 알기 위해서는 서버에 몇 명이 있는지 클라이언트로 알려야한다. 플레이 도중에 플레이어가 접속 또는 로그아웃을 할 가능성이 있으니 관련 처리를 위한 이벤트도 필요하다.
이런 문제는 클라이언트가 서버로 접속한 직후에 동작하는 멀티플레이 관련 기능에서 많이 발생한다. 문제를 해결하고 모듈로 만들어 중복된 코드를 줄일 필요가 있다.
요구사항
- 클라이언트에서
GameState
가 유효해지는 시점을 이벤트로 구현할 수 있어야 한다. - 클라이언트에서
PlayerState
가 유효해지는 시점을 이벤트로 구현할 수 있어야 한다. - 클라이언트는
GameState
와PlayerState
가 유효해진 시점을 서버로 알려야 한다. - 서버에서는
PlayerController
를 통해 클라이언트의GameState::PlayerArray
가 서버와 동일한지 확인할 수 있어야 한다.
구현
서버의 이벤트는 IMultiplayServerEvent
인터페이스, 클라이언트의 이벤트는 IMultiplayClientEvent
인터페이스를 통해 구현할 수 있도록 만든다. GameState::BeginPlay()
와 PlayerState::BeginPlay()
에서 클라이언트 이벤트를 호출하고, IMMultiplayClientEvnet
인터페이스를 상속받은 PlayerController
의 RPC를 통해 IMultiplayServerEvent
인터페이스를 상속받은 GameMode
에 이벤트를 호출해 서버에서 클라이언트가 유효해진 시점을 확인할 수 있도록 만든다. 클라이언트에서 유효한 PlayerState
가 바뀔 때마다 유효한 PlayerState
목록을 서버로 전달한다면 서버에서 GameState::PlayerArray
와 전달된 목록을 비교하여 해당 PlayerController
가 서버와 동기화 되었는지 확인할 수 있게 된다.
실질적인 구현은 Git 레포지토리를 확인하면 된다. 플러그인 형태로 만들어서 만들고 있는 프로젝트에 추가하면 바로 사용할 수 있다.
사용법
플러그인에서 구현된 MultiplayGameMode
, MultiplayGameState
, MultiplayPlayerState
를 상속하면 MultiplayServerEvent
인터페이스와 MultiplayClientEvent
의 이벤트가 호출된다. 4번째 요구사항인 동기화 여부는 MultiplayPlayerController::HasAllSyncedPlayerStates()
함수를 사용해서 알 수 있다. 단, 클라이언트에서는 GameState::PlayerArray
가 항상 서버보다 동기화가 늦기 때문에 최신 여부를 확인할 수 없고, IMultiplayClientEvent::LocalPlayerStateBegin
, IMultiplayClientEvent::OtherPlayerStateBegin
이벤트로 받아오는 PlayerState
가 최신임을 가정하고 구현해야 한다.
'개발일지 > UE5' 카테고리의 다른 글
3D 미니맵 플러그인 `PerspectiveMinimap` 개발 (0) | 2024.07.03 |
---|---|
스플라인 메시로 회전 가능한 도로 만들기 | Spline Road with roll and scale (0) | 2024.06.13 |
LyraStarterGame 시스템으로 개발 중 언리얼을 재시작하면 위젯과 레이아웃 사라지는 문제 (0) | 2024.05.27 |