본문 바로가기
개발일지/ChopChop

[ChopChop] 3. SDK 적용

by heydotory 2025. 2. 16.

[2024-10-13]

업적을 관리하기 위해 플랫폼의 SDK를 넣어야 했다.
SDK의 함수를 통해 통계 설정, 업적 해금 등의 작업을 진행할 수 있다.
언리얼 엔진은 OnlineSubSystem 플러그인을 통해 해당 작업을 쉽게 할 수 있도록 하고 있다.

OSS 플러그인

 

그런데 내가 직접 해보니 그렇게 쉽게 해결될 문제가 아니었다.

과정을 간단히 요약하자면


1. OnlineSubSystem을 사용해 봤으나
기능에 제약이 많다.
  
) IndicateAchievementProgress (업적 진행상황을 띄워주는 스팀의 기능) 같은 독특한 기능은 OSS로 구현할 수 없다.
2.
스팀, 에픽 각 플랫폼마다 같은 기능을 제공하는 경우가 있다. (업적 해금, 통계 설정 등 공통적으로 들어갈 수 있는 내용)
하지만 플랫폼 간 성격이 다르기 때문에 서로 다른 이름의 함수, 다른 인자가 필요하도록 함수를 정의한다.

OSS는 이것을 하나로 처리하려고 하다 보니까 Steamworks 문서와 사용 방법이 다른 경우가 있었다.

함수가 작동을 안 하면 문서를 보고 문제를 수정해야 하는데 이게 힘들어 비직관적이라고 생각했다.
3.
위 문제들로 인해 플러그인이 아닌 SDK를 직접 받아 C++기반으로 만들려고 했다.
4.
플러그인 형태로 만들어야 다른 프로젝트 할 때 적용하기 편할 것 같아서 플러그인 만들기를 공부했다.
5.
플러그인 만들고 SDK를 넣어서 빌드 후 실행해 봤는데 Init, GetStat 등 처음 다뤄보는 개념이 있어 이렇게 하는 게 맞는 것인지 확인하기 힘들었다.
더구나 기존 게임 개발에 사용하고 있는 log 때문에 확인이 쉽지 않았다.
6. 비주얼 스튜디오로 빈 C++ 프로젝트를 만들고 여기에 SDK를 연동시켜 Init, GetStat, ResetAllStat 등 원하는 기능이 제대로 작동하는지 간단한 프로그램을 만들어 테스트했다.
7.
완벽하게 작동하는 법을 찾고 이 방법과 흐름을 언리얼에서도 동일하게 구현, 테스트하였다.

 

스팀 SDK를 직접 넣는 데에는 다음의 튜토리얼이 큰 도움이 되었다.

https://youtu.be/SyCeumSqtbM?si=ZHXwdblhIGWpaFXw

 

이 과정에서 스팀 오버레이가 안 떠서 많은 애를 먹었는데, 이를 해결하기 위해서는 게임보다 스팀 Init이 빠르게 되어 SDK OpenGL/D3D장치와 연동될 수 있도록 해야 한다.

https://partner.steamgames.com/doc/features/overlay

 

Steam Overlay (Steamworks Documentation)

Documentation Resources News & Updates Support

partner.steamgames.com

다음의 과정으로 해결했다.

  1. 언리얼로 플러그인을 만들면 StartupModule() 함수가 있다. 여기서 SteamAPI_Init()을 불러준다.
  2. .uplugin을 편집기로 열어 LoadingPhaseEarliestPossible로 바꿔준다.

오버레이 하나 띄우기 참 어렵다.

 

외부 SDK를 사용하는 것은 처음이라 어떤 순서로 함수를 불러야 하는지,

통계랑 업적이랑 무슨 상관이 있는지 도무지 감이 잡히지 않아서 그 개념을 이해하는 것이 오래 걸렸다.
나중에 에픽, 스토브 SDK에서도 비슷한 고생을 하게 된다.

각 플랫폼별 구현 방법이 달라 이걸 하나의 프로젝트에서 사용하기 위해 어떠한 과정을 거쳐야 하는지 많은 고심을 했다.

Steamworks SDK 연동 테스트를 위한 UI를 만들었다.
버튼을 누르면 로그를 출력한다. 버튼을 누를 때마다 내가 플랫폼과 통신하고 있다는 게 느껴져서 신기하다.

 

한 가지 더, SDK 예외처리를 생각해 내는 게 힘들었다.
-
통계에는 벌목 횟수가 있는데, 이걸 1번 팰 때마다 SetStat을 해야 하는가? 아니면 일정 주기마다 해야 하는가?
  -> 모든 플랫폼에는 분당 호출 횟수에 제한이 있으므로 일정 주기마다 SetStat을 하도록 했다.
-
게임이 강제종료 된다면?
  -> Event Destroyed
시에 SetStat을 한다.
테스트하는 것도
시간이 꽤 걸렸다.

 

[2024-11-02]

기존에는 Chop 버튼을 떼서 나무를 패면 나무가 바로 쪼개졌다.
그렇게 하면 도끼를 뒤로 젖히는 의미가 없으므로 나무에 HP를 넣어서 도끼를 완전히 젖혀야만 HP가 모두 닳게 했다.

도끼가 안 젖혀졌을 때 0, 완전히 젖혀졌을 때 1이라고 했을 때 이 젖혀진 만큼 HP를 깎는다.

 

다음으로 나무토막이 쪼개지는 모양을 어떻게 표현할까 고민했다.
여러 방법을 생각해 보았다.


1.
셰이프키를 넣는다.
2.
본을 넣어서 움직인다.
3.
버텍스 셰이더를 사용한다.


일단 모델링을 수정하고 싶지 않았다. 이것저것 얽힌 게 많기 때문이다.
그리고 셰이더를 통해 내가 생각한 방식대로 문제를 해결할 수 있지 않을까 하는 도전적인 마음이 들었다.

만약 성공한다면 재질 하나 바꾸면 끝나는 문제가 돼서 복잡하게 얽힐 일이 없어서 좋다.
이것에 대해 도전해보고 싶어서 셰이더를 수정해 봤고, 생각대로 잘 되어서 놀랐다.

UV2에 쪼개지는 모양대로 UV를 펼치고 이 UV 좌표를 버텍스 포지션에 더한다.

hp가 0~1 값이므로 더하고 싶은 값과 hp를 곱하면 0이면 안 쪼개지고 1이면 완전히 쪼개진 모양이 된다.

 

결과를 봤을 때 아주 뿌듯한 작업이었다.

 

[2024-12-23]

자율심의를 받아야 했다.
PC
게임 출시 자율심의 사업자 후보로 에픽, 스토브를 생각했다.
언리얼과 연이 있고 해외 위주의 스토어라서 에픽 게임즈 스토어에 출시를 하기로 했다.
업적을 동일하게 넣고 싶었기에 Epic Online Services SDK 적용에 도전해 봤다.
스팀에 비해 최근에 나온 플랫폼이어서 그런지 적용 과정에서 다른 점이 많았다.

 

우선 어떤 게임이 SDK를 쓰고 있는지 알기 위해선 게임 고유의 값이 필요하다.
스팀은 appID 하나로 해결한다. 몇 자리 숫자에 불과하다.
에픽은 Client Id, Client Secret, Product Id, Sandbox Id, Deployment Id, Client Encryption Key가 필요하다.

ID는 알파벳과 숫자로 이루어져 있다.

에픽은 훨씬 더 깐깐하다. Advanced 하다고 해야 하나, 내 입장에서는 에픽의 경우가 보안성이 더 강해서 좋다.

스팀의 앱 ID SteamDB에서 쉽게 확인할 수 있으므로 마음만 먹으면 다른 게임 ID GetStat, SetStat을 할 수 있지 않을까 생각했다. 업적을 내 마음대로 해금할 수 있는 것이다. 물론 직접 해보지는 않았다.


통계, 업적등을 정의하는 방법은 스팀과 매우 유사하나 SDK 사용 방법에서 세부적인 부분이 달랐다.

우리가 하려는 작업은 플랫폼 서버와 통신을 하는 것이므로 비동기 방식으로 처리된다.

데이터 요청 -> 데이터 가져오기가 1 프레임만에 해결이 되지 않는 것은 당연하다.

Steamworks 문서의 GetStat 항목

Steam Callback함수를 안 쓴다. GetStat 함수에 데이터를 담을 포인터 변수를 넣어주면  끝이다.

에픽은 데이터를 콜백함수를 통해 알려준다.
한눈에 비교하면 다음과 같다.


-
스팀: GetStat 하고 통계 값을 을 출력하기
-
에픽: 1. GetStat 하고 OnGetStatCompleted가 불릴 때까지 기다리기
           2. OnGetStatCompleted
가 불리면 통계 값을 출력하기


스팀은 SDK 처음 사용이라 오래 걸렸다면, 에픽은 콜백함수 처리를 하는데 애를 먹었다.
콜백함수는 C++이고 내가 원하는 기능은 블루프린트로 연결해 쓰고 싶어서 C++로 델리게이트를 쓰는 법을 배워야 했다.

 

[2024-12-25]

현지화를 했다.
ChatGPT
로 10개국어로 번역하게 했다.
GPT4
로 무료 사용하다가 검수 과정에서 내 말길을 못 알아듣고 원치 않은 작업을 하길래 한 달 결제하여 o1을 사용했다.

확실히 o1이 내 말을 잘 알아들어준다.
검수할 때
각 줄마다 원어 느낌을 잘 살렸는지 비교하고 이를 표로 보기 쉽게 해달라고 했다.

GhatGPT번역의 장점은 이해가 안 가는 번역을 되물어 볼 수 있다는 점이다. 물어보면 친절하게 답해준다.

 

번역 후 언리얼의 Localization Dashboard를 사용해서 게임 내 텍스트를 번역했다.
이 방법을 처음 알았을 때는 재밌다고 생각했다.

우선 번역할 텍스트는 Text 변수로 만들고 플래그를 눌러 Localize를 체크해 준다.

엔진 상단 Tools -> Localization Dashboard를 누른다.

그 뒤 대시보드에서 Gather from Packages 체크 후 어디서 텍스트를 수집할지 파일을 지정해 준다.

나의 경우 UI에서 텍스트를 쓰고 있으니 UI/*를 넣어서 UI 폴더 내의 모든 에셋에서 Text를 수집하게 했다.

그리고 밑에 Gather Text를 하고 번역본을 입력, Compile Text를 하면 적용이 된다.

번역본 입력하기

 

게임 내에서 언어를 변경하기 위해서는  SetCurrentCulture를 하면 바로 변경이 된다.

 

내가 잘못 넣었을 수도 있으니 10개국어로 게임을 플레이하면서 화면을 구글번역기로 돌리며 다시 검수했다.

'개발일지 > ChopChop' 카테고리의 다른 글

[ChopChop] 5. 게임 최적화 하기  (0) 2025.02.18
[ChopChop] 4. 게임 출시하기  (0) 2025.02.16
[ChopChop] 2. UI로 고통받기  (0) 2025.02.16
[ChopChop] 1. 게임 개발 시작하기  (0) 2025.02.15