프라우드넷 스터디 2

2017. 10. 25. 10:30기술/네트워크

반응형

프라우드넷 스터디 1에서

유니티를 사용한 클라이언트가 서버에 연결하기, PIDL 파일을 만들고 메시지주고 받기를 해보았습니다.

결론적으로는 이렇게 간단하지만 세부적으로 보면 복잡한 내용들이 있습니다.


동영상에서 #include "헤더파일.h"를 선언해 주는 부분이 안 보이는 경우가 있는데 알맞는 부분에 추가해주어야 합니다.


스터디 2에서 해볼사항들은 다음과 같습니다.

클라이언트

1. 유니티 에셋 다운로드

2. 터치된 지형에 나무 심기

서버

1. 전송된 나무위치를 다른 클라이언트에게 알리기(Notify)

2. PIDL의 파라메터 다루기 마샬링(Marshaler)에 대해서 알기


일단 아무거나 다운받아도 상관없겠죠. 아름다운 배경 모델링은 아트디렉터(AD)와 배경모델러의 역할입니다.


유니티의 GameClient.cs에서 수정된 사항은 다음과 같습니다.


GameClient.cs



OnGUI 함수에서는 GUI.Label이라든가 버튼을 렌더링 해주는 역할을 하고 Update() 함수에서 마우스 픽킹관련된 기능을 수행합니다.

Update_Ville()에서 Input.GetMouseButtonUp(0)으로 마우스가 클릭되었는지 여부를 받아온 다음

카메라 스크린위치에서 광선을 쏘아 지형에 충돌한 지점까지 광선을 만들어냅니다.

클릭된 오브젝트의 이름이 Terrain이면 서버로 "나무를 추가하겠다."라는 메시지를 송신합니다.


그럼 서버에서는 접속되어 있는 다른 클라이언트들에게도 "나무를 추가하겠다."라는 메시지를 알립니다.

그 함수가 NotifyAddTree함수이고 서버에서 이 메시지가 수신될 때 해당 위치에 나무 프리팹을 생성(Instantiate)합니다.


서버쪽에 수정된 사항은 다음과 같습니다.


Social.pidl



rename cs(D3DXVECTOR3, UnityEngine.Vector3);
이 부분은 cs파일에서 D3DXVECTOR3를 UnityEngine.Vector3로 바꾼다(rename)라는 의미입니다.


[marshaler(cs)=SngClient.Marshaler]
이 부분은 cs파일의 마샬러를 선언해주는 부분입니다.
마샬링은 함수의 매개변수를 변환하는 기능입니다.
마샬링에 대해서 더 깊이있게 다루려면 시간이 필요합니다.

유니티에서 Marshaler.cs 파일을 만들고 다음과 같이 입력합니다.


일단은 "나무를 추가하겠다."라는 메시지 요청을 수신하면 "나무를 추가하겠다를 알립니다." 함수만 추가해줍니다.

ServerStudy.h


ServerStudy.cpp




서버를 켠 상태에서 지형(Terrain)을 클릭하면 나무가 생성되는것을 확인할 수 있습니다.


- 여기까지 동영상4 입니다.


여기에서 부터는 코드를 작성하고 찬찬히 살펴보다 보면 이해할 수 있습니다.


CWorldObject.h, CWorldObject.cpp


CVillage 클래스에서 하는 역할은 주로 p2p그룹으로 묶기, 마을에 플레이어 추가/제거, 월드오브젝트 추가/제거입니다.

CVillage.h, CVillage.cpp


CRemoteClient.h, CRemoteClient.cpp


서버에서 수정사항은 다음과 같습니다.

1. 접속 해제시 마을에서 플레이어를 삭제하고 모든 플레이어가 마을에서 떠났을 때 마을 삭제

2. 클라에서 로그인 요청시에 마을 생성과 P2P그룹생성, 플레이어 생성, 새로 들어온 플레이어에게 이미 추가된 나무들 알림(Notify)

CServerStudy.cpp


여기까지 하면 6명의 플레이어가 동기화로 마을에 함께 나무를 심을 수 있습니다. 물론, 한 마을에 플레이어 제한 수가 없기 때문에 현재로서는 무제한 인원이 함께 플레이 할 수 있으나 제가 사용하고 있는 프라우드넷 계정은 10명까지 될 것입니다.



 네트워크를 통한 자료구조에서 오브젝트 찾기


 이쯤되면 프로그래머도 사람이기 때문에 이제 헷갈려지기 시작하는게 생깁니다.

바로 클라이언트에서 무엇을 요청할 때 서버에서 무엇을 응답하고하는 것들입니다. 헷갈라지 않으려면 UML 시퀀스 다이어 그램으로 그려서 보면 됩니다.

 실무에서는 UML으로 클래스 다이어그램을 그리고 기획자와 서버프로그래머와 함께 봐야 하겠습니다.


 나무를 삭제하는 기능을 추가해보도록 합니다.


 나무의 ID가 언제 할당되어야 하는가? 그것은 클라에서 나무를 추가하겠습니다. RequestAddTree 요청을 했을 때 서버에서 나무(tree)의 ID를 할당합니다. 그 다음 서버에서 클라로 나무가 추가되었습니다를 통보할 때 NotifyAddTree 응답시 나무의 ID를 알려주고 클라에서는 그 ID를 가지고 있으면 됩니다.


 그 다음 클릭했을 때 선택된 오브젝트가 지형이 아니고 나무이면 서버로 나무를 지우겠습니다. RequestRemoveTree 요청을 합니다. 서버에서는 마을의 월드오브젝트 자료구조에서 해당 나무 ID를 삭제하고 P2PGroup에 나무가 지워졌습니다를 통보합니다. NotifyRemoveTree 이때 나무의 ID를 알려주면 클라에서 나무 자료구조의 ID를 찾아서 게임 오브젝트를 삭제해 줍니다.


CServerStudy.cpp


GameClient.cs, WorldObject.cs


P2P


 이번에 알아볼 것은 프라우드넷 서버엔진의 P2P 기능입니다. 기존에 RequestAddTree는 서버에 요청하는 메시지였습니다. C2SProxy였었죠. 하지만 P2P는 서버를 거치지 않고 클라이언트에서 클라이언트로 바로 메시지를 보내는 기능입니다. 그리고 보낼 때, RmiContext.UnreliableSend로 보낼 수 있는데 메시지가 손실되도 상관없다는 의미입니다. 주로 캐릭터의 위치정보를 보냅니다.


 그리고 DB서버에 저장을 해야할 필요가 있는 메시지는 서버로 보내는 것이 맞고 DB서버에 저장을 해야할 필요가 없는 정보는 P2P로 보내주어도 될 것 같습니다.

 ReliableSend로 보내면 메시지가 손실되지 않고 도착하는데 캐릭터 N vs N 전투시에 동작과 같은 정보들은 P2P로 보내도 상관이 없고 결과에서 승패 정보라든가 기록 정보는 서버로 전송하면 될 것입니다.



 프라우드넷 튜토리얼 동영상 6 에서는 이 기능을 사용하여 흰박스를 빠르게 그려주는 예제를 알려주고 있습니다. 


Social.pidl


 일단은 PIDL에서 함수를 하나 더 선언해서 P2P 함수를 만들어줍니다. D3DXVECTOR3로 선언하면 유니티에서는 자동으로 UnityEngine.Vector3로 변환되기 때문에 상관없습니다.


GameClient.cs


 서버 코딩은 주로 필요가 없고 유니티에서 SocialC2C.Proxy, Stub 맴버 변수 선언과 netClient 객체에 Attach를 해줍니다. 그리고 포인트를 찍는 ScribblePoint 함수를 연결해 주고 구현해 줍니다.

 UI적으로는 OnGUI를 사용하여 버튼을 그려주고 클릭시 나무 추가 모드인지 흰박스 그리기 모드인지를 변환합니다.


 Update()함수에서 버튼이 눌렸고 eFingerMode.Scribble 모드이면 m_C2CProxy를 사용해서 같은 그룹의 P2P 클라이언트들에게 hit.point 위치 메시지를 전송합니다. RmiContext의 enableLoopback = true;로 해주면 메시지를 자기 자신한테도 보낼 수 있습니다.


 이 메시지를 받았을 때, goScribblePrefab을 point위치에 생성(Instantiate) 해주고 AutoDelete.cs 파일을 만들어 Box 프리팹에 넣어주고 Start()함수에서 Destroy(gameObject, 1);을 해주면 1초뒤에 흰박스 게임오브젝트가 파괴되게 됩니다.




 튜토리얼 동영상 7~9는 DB관련이므로 다음에 필요시 익혀보도록 하겠습니다. DB관련은 서버 프로그래머분이 있어야 하며 제가 여기까지 익힌 이유는 N VS N 네트워크 전투를 구현하기 위해 필요한 지식을 습득하기 위함이었습니다. DB쪽을 더 보기 보다 N VS N 네트워크 전투에 집중하도록 하겠습니다.



반응형