언리얼 Documentation에 소개된 Multiplayer Programming Quick Start Guide를 많이 참고하며 기능들을 구현했다.

 

PlayerStart 액터를 맵에 두 개 배치하고 플레이어 2명, 멀티플레이 옵션을 ListenServer로 세팅하고 플레이하면 캐릭터의 움직임은 Character Movement 컴포넌트에 의해 레플리케이션 되지만 발사 입력이 들어왔을 때 생성되는 Bullet Actor에 대한 레플리케이션 설정은 해주지 않았기 때문에 총알을 발사해도 상대방 입장에서는 보이지 않는다.

 

RepNotify를 이용해 체력을 리플리케이트하고,  WeaponComponent의 Fire 함수를 RPC함수로 만들어 서버에서 먼저 Bullet이 생성되도록 한다.

 

RepNotify (변수 리플리케이션)

ReplicatedUsing 지정자는 네트워크를 통해 프로퍼티를 업데이트할 때 실행되는 콜백 함수를 지정한다.

CurHealth를 서버에서 변경할 때마다 서버에 연결된 각 클라이언트에서 OnRep_CurrentHealth가 실행된다.

 

Replicated로 지정된 프로퍼티를 리플리케이트하려면 반드시 이런 형식으로 GetLifetimeReplicatedProps 함수를 구현해줘야 한다.

 

순서

1. Bullet에서 ApplyPointDamage 함수를 호출하여 캐릭터는 TakeDamage 함수를 호출한다.

2. TakeDamage가 서버에서 SetCurrentHealth 함수를 호출하여 체력 값을 변경시킨다.

3. SetCurrentHealth는 서버에서 호출될 경우에만 CurHealth 값을 변경한다. 이것은 클라이언트들의 OnRep_CurrentHealth를 호출한다. OnRep_CurrentHealth는 플레이어의 체력 변경에 반응하는 모든 함수 기능을 실행하게 한다. (Role을 확인하여 서버, 클라이언트에 따라 다른 방식으로 반응할 수 있음)

서버에서 CurHealth를 변경해도 클라쪽에서만 OnRep_CurrentHealth가 호출되기 떄문에 OnHealthUpdate를 직접 호출해줘야 한다. C++과는 다르게 블루프린트로 작업하는 경우는 OnRep_CurrentHealth가 서버와 클라이언트 모두에 호출된다고 한다.

4. CurHealth가 각 클라이언트 캐릭터에 리플리케이트 된다.

5. 각 클라이언트는 OnRep_CurrentHealth를 호출한다.

6. OnRep_CurrentHealth 는 OnHealthUpdate를 호출한다.

 

RPC를 사용하지 않고 RepNotify를 사용한 위의 방법이 체력 변경을 리플리케이트하는 가장 효율적인 모델이라고 한다.

 

Bullet.cpp

액터의 리플리케이션은 단순히 bReplicates 플래그를 true로 설정해주면 끝이다.

Bullet의 생성자 내부에서 설정한다.

 

Bullet의 콜리전 컴포넌트에 대한 충돌 처리 또한 서버에서만 일어나도록 Role을 확인

 

RPC 함수

클라이언트에서 호출되는 모든 Fire은 서버에서의 Fire_Implementation으로 대체된다.

 

RPC 함수의 구현부는 _Implemntation의 접미사를 함수 이름에 추가해줘야 한다.

 

 

이제 리플리케이션을 적용하여 멀티플레이어 환경에서 상대 플레이어에 대한 데미지 적용과 총알의 동기화가 되었음을 확인했다. 사운드, 애니메이션 몽타주들은 아직 적용을 안해봤는데 해볼 예정이다.

결과물

 

+ Recent posts