언리얼 네트워킹 학습



https://docs.unrealengine.com/latest/KOR/Gameplay/Networking/Actors/index.html 



[ 액터 업데이트 방식 ]


 1) 프로퍼티 : 변경될 때마다 자동으로 리플리케이트 : 생명력 등 자주 변경되는 프로퍼티

 2) RPC (Remote Proceduce Call) : 실행될 때만 리플리케이트 : 특정 위치에서 보이는 폭발 등



[각 오브젝트]


 

항목 

 설명

1

Game Mode

 서버에만 존재

2

Game State

 서버 / 클라이언트에 존재 (서버쪽에서 클라이언트로 최신화)

3

Player Controller

 모든 클라이언트에 대하여 서버에 존재

 따라서 리플리케이티드 프로퍼티를 저장하면 안됨

4

Player State

 모든 클라이언트에 대하여 서버와 클라이언트 양쪽에 존재 : 

 각 플레이어의 현재 점수와 같은 리플리케이티드 프로퍼티에 사용

5

 Pawn / Character

 서버와 모든 클라이언트에 존재, 

 리플리케이티드 변수 및 이벤트를 가짐  


 #. 특정 변수에 대한 Player State vs Pawn 

   - PlayerState는 플레이어가 접속된 시간동안 유지됨

   - Pawn은 리스폰 등의 이유로 소멸될 때 새로운 Pawn을 생성하기 때문에 유지되지않을 수 도 있음



[ 액터 리플리케이션 ]


1) Replication-Replicates 옵션이 True로 설정된 액터는 서버에서 연결된 클라이언트로 자동 동기화 됨.

2) 액터는 서버 -> 클라이언트 가능 / 클라이언트 -> 서버 불가능

3) 클라이언트에서 서버로 데이터를 전송하려면 리플리케이트 되는 'Run on Sever' 이벤트를 통해 이루어짐



[ 오쏘리티 ]


1) 월드의 모든 액터에 대해서 접속된 플레이어 중 하나는 해당 액터에 대해 오쏘리티가 있음

2) 서버는 서버에 존재하는 리플리케이티드액터를 포함하여 모든 액터에 오쏘리티가 있음  

3) 클라이언트에서 Has Authority 함수가 실행되고, 타겟이 그에게 리플리케이트된 액터인 경우, False를 반환함.

4) Switch Has Authority 매크로를 사용하여 리플리케이트되는 액터에서 서버와 클라이언트에 따라 다른 동작을 하도록 하는 분기를 만들 수 있다.



[ 변수 ]


 - 액터상의 변수에 대한 디테일 패널에서 리플리케이션 방법을 조정가능


 옵션

설명

 None

 없음 : 디폴트 값. 이 변수를 네트워크를 통해 클라이언트에게 전송하지 않음.

 Replicated

 리플리케이트 : 서버가 이 액터를 리플리케이트하면 클라이언트에게 전송함.

                     받는 클라이언트의 변수 값은 자동으로 업데이트 됨. 

                     다음 번 접근할 때 서버상에 있던 값을 반영함.

                     리플리케이트 변수는 서버 -> 클라이언트 로만 전송됨.

 RepNotify

 리플 알림 :  리플리케이트에 추가로 블루프린트에 OnRep_<변수명> 함수가 생성됨.

                  이 함수는 변수의 값이 변할 때마다 서버와 클라이언트에서 엔진에 

                  의해 자동호출됨.

 - 해당 변수를 'Set' 할 때 호출된다. 스트럭쳐를 Set in member로는 호출 안됨.

 


[ 스폰 및 소멸 ]


 1) 스폰

 리플리케이트 위치

 사본 생성 여부

 사용처

 서버

 클라이언트에 

사본 생성

 게임 플레이에 영향을 끼치고 리플리케이트시켜야 하는 액터에 사용

 클라이언트

 서버에 

사본 생성 X 

 게임 플레이에 영향을 주지않는 장식성 액터에 사용.


 2) 소멸

 리플리케이트 위치

사본 소멸 여부

 사용처

 서버

클라이언트의 

사본 소멸

 리플리케이트 되는 액터를 소멸시켜야 하는 경우, 서버에서 소멸해야 함.

 클라이언트

 존재 X 

 클라이언트가 오쏘리티를 갖지 않은 액터를 소멸 시도하는 경우 무시됨.



[ 오너십 ] 


 - Run on sever 이벤트는 클라이언트가 소유하는 액터에서만 호출 가능함.

 - 즉, 다음의 액터 또는 액터 중 하나의 컴포넌트에서 호출 가능

    1) 클라이언트의 PlayerController

    2) 클라이언트의 PlayerController가 빙의된 Pawn

    3) 클라이언트의 PlayerState 


 - 마찬가지로 Run on owning Client 이벤트를 전송하는 서버의 경우, 그 이벤트 역시 이 액터 중 하나에서 호출되어야함. 그렇지 않으면 서버는 이벤트를 전송할 클라이언트를 알지 못하게 되어 서버에서만 실행됨.



[ 이벤트 ]


 - 커스텀 이벤트의 디테일 패널에서, 이벤트 리플리케이션 방식을 설정할 수 있음.


옵션

실행

설명

 Not Replicated

Sever

 서버에서만 실행.

Client

 클라이언트에서만 실행

 Multicast

Sever

 타겟 오브젝트를 어느 접속에서 소유했는지 무관하게 

 접속된 모든 클라이언트에 리플리 케이트

Client

 리플리케이트되지 않은 것으로 간주,
 호출한 클라이언트에서만 실행 

 Run on Sever

Sever

 서버에서만 실행

Client

 클라이언트가 소유한 타겟으로 실행된 경우 

 서버에 리플리케이트되어 실행 

 Run on 

Owning Client

Sever

 타겟 액터를 소유한 클라이언트에서 실행됨.

 서버는 액터 자체를 소유할 수 있어서 이름과 무관하게 서버 실행가능.

- 서버에서 실행해서 리플리케이트하는게 아니라 해당 액터에서만 실행됨 주의하자.

Client

 이벤트는 리플리케이트되지 않은 것으로 간주, 

 호출한 클라이언트에서만 실행  

 


1)  서버에서 이벤트가 호출 되었을 때 기준 실행되는 곳은...


타겟

Not Replicated

Multicast

 Run on Sever 

Run on Owning Client 

클라이언트
소유 타겟

 서버 

 서버 + 모든 클라

 서버

 타겟의 소유 클라

서버

소유 타겟

 서버

 서버 + 모든 클라

 서버

 서버

 미 소유
타겟

 서버

 서버 + 모든 클라

 서버

 서버



2)  서버에서 이벤트가 호출 되었을 때 기준 실행되는 곳은...


타겟

Not Replicated

Multicast

 Run on Sever 

Run on Owning Client 

호출 클라

소유 타겟

 호출 클라

 호출 클라

 서버

 호출 클라

다른 클라
소유 타겟

 호출 클라

 호출 클라

 X

 호출 클라

서버 소유 타겟

 호출 클라

 호출 클라

 X

 호출 클라

미소유 타겟

 호출 클라

 호출 클라

 X

호출 클라



[ 중도 참가 고려사항 ]


 - 중도 참가가 가능한 게임의 경우 참가 전에 일어난 리플리케이트 되는 이벤트는 새 플레이어가 알지 못함.

 - 때문에 리플리케이트 되는 변수를 통해 게임 플레이 데이트를 동기화 시키는 것이 최선.



[ 신뢰성 ]


 - 리플리케이트 되는 이벤트에 대해 Reliable(신뢰성) 인지 Unreliable(비신뢰성) 인지 선택 가능.


 신뢰성

 도달여부

 대역폭 

 주의 

 Reliable

 목적지에 반드시 도달

 많은 대역폭 필요, 지연시간 길어짐

매 틱 전송하지 말 것. 

 Unreliable

 목적지에 도달하지 못할 수도

 적은 대역폭 필요

 자주 호출해도 안전




------------------------------------------------------------------------------------------------------------------



[ 플레이어 수 설정 ]


 - 플레이 버튼 옆 화살표를 누르고 Number of players 의 숫자를 바꿔줌.


[ 플레이 고급 세팅 ]

 

 - Advanced Settings를 눌러 추가 세팅을 설정 가능

 - Number of Players : 에디터와 리슨 서버는 플레이어로 치지만, 데디케이티드(전용) 서버는 치지 않음

 - Run Dedicated Sever : 체크하지 않으면 첫 플레이어는 리슨 서버 역할을 하여 나머지 플레이어가 거기 접속함.

                                 일반적으로 데디케이트 서버를 사용하는 것이 훨씬 쾌적한 플레이 환경을 제공함.

 - Use Single Process : 하나의 언리얼 엔진으로 다수의 플레이어 창을 스폰함



[ Player Index ]

 - 만약 로컬 LAN 멀티라면 Player Index를 신경써야하지만, 인터넷 연결하는 게임이면 

   모든 플레이어가 Index 0 을 갖는다.


------------------------------------------------------------------------------------------------------------------


[ 리플리케이트 ] 

 - 대부분의 이벤트는 Run On server 이벤트를 호출하고 그 이벤트를 multicast로 호출하여야 모든 플레이어가 그 이벤트를 볼 수 있다.


------------------------------------------------------------------------------------------------------------------


[ 네트워크 컴포넌트들의 테스트 ]
 - single process로 실행해야함!
 - 주의할 점은 언제나 서버-> 클라이언트 클라이언트->서버 클라이언트->클라이언트 세가지 경우를 봐야함.



------------------------------------------------------------------------------------------------------------------

플레이어용 블루프린트에서 Get Player Controller 를 썼던 것들을 전부 Get Controller로 바꿔야 해당 폰을 가진 플레이어를 구한다.


플레이어 컨트롤러가 필요한건 Pure Cast를 활용.


------------------------------------------------------------------------------------------------------------------


서버에 리플리케이트 한다고해서 클라->서버 로 정보가 넘어가지않음.

클라-> 서버는 반드시 RunOn Server이벤트로 값을 넘겨주고 거기서 Set을 해야함.


--------------------------------------------------------------------------------------------------------------------


카메라는 리플리케이트시키면 안됨.. 헤드는 어차피 자기자신한테는 안보이니까 카메라 하위로 두지말고 따로 리플리케이트하자!


--------------------------------------------------------------------------------------------------------------------


이중 멀티캐스트현상! 해결

https://answers.unrealengine.com/questions/181581/how-do-i-replicate-my-camera-rotation.html 

Get Player Pawn 과 Self를 비교해서 같지않을경우 실행하도록 하면됨 ㅎ



--------------------------------------------------------------------------------------------------------------------


 클라이언트 이동 테스트 세가지 방법!

10_Replicate Movement

11_Replicate Movement 체크해제, 직접 액터 리플리케이트함

12_Replicate Movement의 소수점삭제를 2번째 자리까지 보존


 - 다 똑같음. 그냥 1번째 자리까지 보존으로 설정했음.


[ 구현사항 총정리 ]

 - 플레이어의 이동은 Replicate Movement를 그대로 사용한다.

 - 네트워크 대역폭(bandwidth)을 ini 파일에서 바꿔준다.

 - 카메라랑 컨트롤러는 Event Tick에서 실시간으로 업데이트 하되, 


GameMode에서 모든 Player Controller를 호출하고 세이브할때는 반드시 Owning Client 이벤트로 실행해야한다.

데이터를 로드할때는 반드시 Server로 데이터를 보내서 Set해주는게 필요



[깨달음 목록 : 중요도 순]


1) 클라이언트는 GameMode를 호출 할 수 없다. Get GameMde를 하면 Fail이 난다. Run On Server 이벤트에서 호출해야함.


2) 서버에서 플레이어 캐릭터의 정보를 가져와봤자 실제 플레이어가 가지고 있는 정보랑 다르다. 플레이어 쪽에서 Run On Server 이벤트로 데이터를 보내줘야한다.


3) Replicate 변수는 서버가 플레이어한테 정보 보낼때 사용하는거다. 클라이언트 쪽에서는 절대 사용하지말자.


4) seamLess로 씬을 열면 PlayerController가 보존된다. 


5) PlayerController에 있는 데이터를 리셋하려할 때, Function에서 했더니 리플리케이트가 안되서 적용이안됨. 별도로 Function을 호출하는 Own_Client 이벤트를 만들어서 호출하자.


6) 리플리케이트 변수는 서버->클라이언트로 넘겨줄 때만 사용 되는 것이다!


7) Run Owning Client는 서버 에서 실행해서 소유한 클라이언트에게 리플리케이트 하는 것이다. 즉, 정보값들은 전부 서버에 있는 것으로 실행되기 때문에 자칫 잘못하면 클라이언트의 정보를 초기값으로 덮어씀.


8) Run Owning Client 이벤트 중 Run On Server 이벤트를 호출하면 오류가 나는듯하다.


9) 왠진 모르겠지만 Player Controller 에 is valid를 쓰면 오류가 남.


10) 데이터가 업데이트 되지않는 경우, 대부분 delay 0.2 초를 사이에 넣어주면 잘 된다.


댓글

Designed by JB FACTORY