본 프로젝트는 정말 감사하게 위 영상에서 제시해준 로드맵을 기반으로 진행되었다. 상시숭배 할 수 밖에 없어
전체적인 흐름
01:32 ▶ 나무위키를 pdf로 저장, GPTs에 첨부하여 참고 지식으로 사용 01:57 ▶ 게임에서 뜯어온 마키세 음성파일에 대해, OpenAI의 whisper을 사용하여 대본 작성 02:04 ▶ GPT store에서 검색한 prompty(GPT 세팅방법을 알려주는 GPT)에게 도움! 요청 02:23 ▶ prompty에게 받은 내용을 번역 후 그대로 마키세 GPTs Instructions에 투입. 추후 음성 지원도 위한 일본어 대답 옵션도 추가. 02:40 ▶ GPTs는 현재 api 지원을 하지 않기 때문에, Selenium(Chrome비슷한거)으로 직접 웹페이지에 접속해 채팅을 이어가는 설계. 02:45 ▶ 웹앱 환경에서, 크리스의 대답중엔 '보내기' 버튼이 비활성화 되는 것을 감지하는 로직 활용, GPT에게 물어보아 셀레니움 환경 완성. 02:55 ▶ 프로그램 UI 작성 시작. 초안을 GPT에게 던져 Python으로 UI 작성. 03:11 ▶ 상기 작성한 일본어 대본을 사용하여 VITS(TTS AI)학습 03:17 ▶ 셀레니움 환경에서 얻어낸 GPTs의 답변을 TTS와 결합
보면 생략된 내용도 있어보이는데, 셀레니움에 대한 내용이 많이 나오지 않았고, 일본어 대본이 아닌 한국어 대본을 어떻게 준비하였는지도 알 수 없으며, 실시간으로 UI에 텍스트가 자연스럽게 나오는 방법도 알 수 없다. 텍스트 갱신과 관련해서는 OpenAI API 다룰 때 보였던 설정과 비슷한건가 싶긴 한데 나중에 찾아봐야겠다.
초기 준비물 확인
나무위키 PDF / 크리스 음성파일 → 대본 파일
게임은 이미 구매했었고, ChatGPT도 지금 가입이 막혔다고 하는데 이미 유료 구독중이라 문제 없다.
슈타인즈 게이트 보이스 파일 준비
슈타인즈 게이트 언팩에 관해서는 https://github.com/rdavisau/sg-unpack 의 힘을 빌렸다. 스팀판 이전의 슈타인즈 게이트 정보와 스팀판의 슈타인즈 게이트 정보가 인터넷에 뒤섞여있는데, 예전의 Voice 리소스파일은 NPA 확장자를, 현재는 MPK 확장자를 사용하고 있다. 듣기로는 크게 다를건 없긴 하다는데 Unpack 같은 키워드의 부재로 깃허브 페이지를 찾지 못하면 인터넷에서 한참을 헤멘다.
스팀 라이브러리 우클릭해서 로컬 폴더를 찾아들어가 경로를 확인한 후, 깃허브 페이지에 친절하게 나와있듯이 명령어 한번으로 쉽게 보이스 파일을 얻을 수 있다. 아래는 cmd에서 입력 예시.
일단 제대로 대본이 나온다는 것은 확인되었고, 야수의 심장으로 WebUI에 3천개 가량의 파일을 한번에 드래그 해 놓았다. 업로드를 기다리는 중이다. 업로드가 끝나면 Generate 버튼을 눌러 대본을 생성하는데, 코랩 노트북 페이지의 파일시스템 중 outputs 폴더에 대본이 생성된다. 왠지 전체선택 다운로드라는 선택지는 없어보였기 때문에 3천개의 대본을 압축 후, 다운로드 받을것이다.
WebUI에 너무 많은 파일을 업로드하면 잘 작동하지 않아, 파일을 600개씩 업로드하는 걸로 타협하였다. WebUI의 설정에서 Japanese 와 txt 출력을 제대로 선택하여, 약 3800개 정도의 대본을 생성했다. 2900개의 origin 대본을 생성한 후, Colab 에서의 코딩을 통해 압축을 하여 다운받아주고, 이어서 900개정도 되는 zero의 대본도 작성후 압축 및 다운로드 하였다.
또한 바로 다음과정인 Prompty에 첨부하기 위해, 파이썬 프로그램을 작성하여 모든 텍스트 파일을 한 개의 텍스트파일 '대본.txt'로 병합하였다.
Prompty를 통한 GPT봇(마키세 크리스) 세팅
Prompty는 GPT를 세팅하거나 질문하는 법에 대해 알려주는 GPT이다.
GPT Store 에서 prompty를 검색하고, Try Prompty를 눌러 사용을 시작한다. 영상과 같이 두 개의 파일을 첨부하여 질문하였다.
GPT의 답변은 복사하는 버튼이 있어 그 버튼을 통해 내용을 복사해도 되지만, 영상에서는, Prompty의 답변을 직접 드래그로 긁어 DeepL 번역기로 한글 번역을 하여 크리스 봇에 세팅하였다.
두 복붙 방법의 장단점이 있는데 아래와 같다.
위 내용은 복사버튼을 통해 내용을 가져온 경우이다. 빨간색 테두리를 친 부분은 답변 내용에 보이지 않았던 필요없는 부분인데, 같이 복사가 된다.
반면에 답변을 전체 드래그해서 복사를 하게 되면 빨간색 테두리를 친 부분은 보이지 않지만, 파란색 테두리로 표시한 제목을 의미하는 ### 나 OL과 UL을 나타내는 숫자나 기호도 모두 누락이 되기 때문에 문제가 되었다.
내 경우에는 복사버튼을 통해 내용을 가져와 필요없는 부분을 모두 지워주는 방향을 택했다. 사실 이렇게 세세하게 하지 않아도 잘 작동할 것 같긴 하다. 그리고 '쿠리수'는 '크리스'로, '스타인즈' 는 '슈타인즈' 로 바꿔주던가 하는 세세한 작업도 하였다.
영상에서 언급한, 일본어와 한국어 양쪽으로 답할 수 있도록 재현해 보았다. 사실 Prompty의 답변이 갈린 시점부터 영상과 유사하게 진행하는것은 어려워졌는데, 어설프게 따라했더니 챗봇에게 아래와 같은 답변을 받았다.
첫 답변만 제외하고는 나름 괜찮게 되었다.
참고로 영상에서의 챗봇은 아래와 같았다.
추후에 대화창 UI에 띄우는 내용은 아마 한글 번역쪽이 되는 듯 하다.
Selenium(셀레니움)을 통한 연결
영상에 언급되기를
'GPTs는 api가 따로 없기 때문에(assistance : 기존 GPT 커스텀 기능 - 어려움, 유료) Selenium으로 api(물리)를 구현 할 예정'
라는 내용이 있어, Selenium을 사용한다고 한다.
지금까지 사용 해 온 GPT의 API는 이전 대화를 기억하지 못하는 일회성 API였기 때문에 매번 호출을 할 때마다 챗봇의 세팅과 과거 로그를 모두 추합하여 요청을 보내야하는 문제점이 있고 비용문제도 확실히 커지게 된다.
과거 Selenium을 사용하여 ChatGPT 페이지를 사용하기 위해 긴 시간을 들여 구글로 로그인하는 문제를 어느정도 완화는 했었다. 기본적으로 봇이 가동중인 웹브라우저는 구글로그인에서 막히기 때문에 외부라이브러리를 사용하여 셀레니움에 약간의 조작을 할 필요가 있었다. 그리고 아이디/패스워드만으로는 구글로그인을 시켜주지 않기 때문에 직접 휴대폰에서 확인을 한번 해주어야 로그인이 되는 것이 그 때의 최종 문제였다.
현재 커스텀 GPTs를 공개 공유링크로 접속해보면, ChatGPT Plus 구독이 필요하며 로그인 버튼이 뜨기 때문에, 위의 로그인 과정은 필요한 것으로 보인다. 아마 영상에서의 셀레니움은 Visual Novel UI 구동과 함께 셀레니움이 동시에 실행되며 그 시점에 최초로 로그인을 한번만 하면 이후 계속 켜져있는 상태로 보인다. 일단 영상에 보이는 상태로는 그렇게 예상되는데, 내 경험에는 셀레니움과 Visual Novel UI(QT인가 싶었는데 코드를 보면 아닌가 싶기도)에서 스레드 점유 문제가 있지 않나 생각되어서 지금 시점에서는 어떻게 될지 모르겠다. 지금껏 그래왔던 것처럼 시간을 갈아넣으면 어떻게든 되지 않을까.
영상을 살펴보는데 파일구조는 아래와 같다.
?????NT.py ChatWaifu.py ChatWaifu_Modified.py // 위 파일을 개선한듯 chromedriver.exe CombinedChatGPTScript.py CombinedChatGPTScript_Full.py // Full과 아닌 코드의 차이점은 모르겠다. 230라인으로 이루어짐. GPT의 대답을 가져옴.
ChatWaifu_WithInputHandling.py // 가장 마지막 단계에 커스텀UI와 셀레니움을 결합하는데에 사용
(단계 완료 후 이어서 작성)
남은과제 : 셀레니움 환경 갖추기 / TTS 변환 모델 작성하기 / UI구성(간단하게는 만들었지만 위 영상처럼은 어떻게 만들었는지 신기함 텍스트 표시 방식 등)
그렇게 긴 기간은 아니었지만 디스코드 봇 배포에 특히 도움을 받은 클라우드타입이, 계속된 업데이트를 거쳐 구독기능이 생기게 되었다. 예정된 날짜는 2023년 12월 7일(목)이고, 지금까지 무료로 사용 가능했던 기능이 일부 제한을 당한다.
어떤 기능들이 있었는지는 대부분 신경쓰지 않았지만, 앞으로 무료 버전 이용자는 매일 실행되고 있는 서비스가 오전 3시 ~ 9시 사이에 중지상태로 만드는 변경점은 상시로 디스코드 봇을 운영하고 있는 입장에서 서비스 종료를 할 수밖에 없다.
클라우드타입의 최소 구독 요금은 월 9,900원으로 적지도 많지도 않은 금액이라고 개인적으로는 생각하는데 다른 플랫폼을 사용한 경험이 없어서 비교는 어렵다. 다만 디스코드봇을 운영함으로써 상시로 서버에서 작동가능한 봇이 매우 활용도가 높다는 점, 플랫폼이 굉장히 깔끔하게 만들어졌다는 점, 기능적인 부분에서 필요하다고 느낀 대부분을 지원한다는 점 등으로 일단은 계속 정착하기로 결정했다.
동료 디스코드 봇 기능 흡수
같은 디스코드 서버에서 함께 클라우드 타입을 사용해 봇을 운영하던 동료분은 봇 운영을 중단한다고 하셔 양해를 구하고 갖고 있던 봇 기능을 이쪽에 도입하기로 했다.
- !듀얼 : '하이', '미드', '로우', '역미드' 네가지 규칙 중 하나를 선정해준다.
- !주사위 : 0~100 사이로 주사위 굴려줌
- !환율(미세개량) : 엔화 및 달러 환율을 알려준다. 숫자나 단위 함께 쓰면 계산도 해줌. 가독성 측면에 신경써서 개량했다.
- !날씨(개량) : 오늘부터 5일 뒤까지의 날씨를 예보해준다. 대충 찍는 건 아니고 tomorrow.io 의 API를 사용했다. 나름 응답받은 자료로 여러가지 정보를 도출해내어 사용자에게 알려준다. 랜덤 이모지 함수도 만들어 환율 명령에도 여기에도 소소하게 사용 해 보았다.
tomorrow.io 날씨 API에 요청을 할 때, 좌표가 아닌 지역이름으로 요청을 할 수 있다는 것을 오늘 처음 알았는데, 이게 심상치가 않다.
오타만 아니라면 왠만한 입력은 다 통과했다. 엄청 시골의 면 단위까지도 지역 입력으로 가능했다. 처음에 예시로써 'seoul'을 사용하는 것을 보고, '아아, 영어로 대도시단위로 틀리지 않고 똑바로 써야 응답해주겠구나' 싶어서 들어오는 입력에 lowcase() 함수도 붙여가며 소문자로 만들어주고 했었는데 헛짓이었다. 아무튼 신기했다. 일단 특수문자랑 공백문자는 모두 제거하고 판단하나보다.
새로 다루는 API이고 기능적으로도 준비하고 싶은 게 많아 하루 내내 여기에 시간을 썼다.
3주차는 리소스 스프라이트가 주어지고, 별도의 Start Scene을 구성하기 등을 배웠다. 4주차는 gameManager 스크립트가 게임의 대부분을 구성하는 같은 그림 찾기 보드게임을 만들었다. 게임 로직에 특히 신경 쓸 부분이 많았다. 5주차는 4주차에 만들었던 보드게임에 효과음과 배경음 넣기, 빌드세팅, '게임 재시작' 단계에 광고 넣기 등 까다로운 부분을 다뤘다.
전체적으로 익숙해지는 느낌이라 학습 정리는 크게 하지 않았고, 5주차에 실습한 내용들이 유니티의 매 프로젝트마다 까다롭다고 생각되는 부분이다. 강의자료의 '광고 넣기' 파트는 예전의 자료였기 때문에 많이 달라져 작동하지 않아 최신 문서를 찾아가며 적용하였다. 현재 Unity Ads를 넣는 방법과 예제 코드는 아래 노션 페이지에 정리 해 두었다. 또한 빌드 시 해상도가 맞지 않을 시 화면을 빠져나가는 자잘한 버그도 스크립트 수정을 통해 해결하였다.
짧은 영상 안에 요즘 트렌드들을 신랄하게 압축 해 놓은 프로젝트이다. 매우 유익한 로드맵을 작성해 준 영상 제작자에게 감사하며, 이 과정을 그대로 진행 해 보기로 생각했다. 슈타인즈 게이트 전 시나리오를 아마 다섯 번 이상 정주행했고(생각나면 찾아봄) 특히 아마데우스 파트는 다른 에피소드와 비교해 윤리 문제를 비롯한 수많은 감정선이 얽혀 있어 미묘한 기분을 느낄 수 있었기 때문에 이 프로젝트에 더욱 관심이 갔다. 해당 영상의 댓글란에 타임스탬프와 함께 기술적인 요소를 함께 적어놓았기 때문에 매번 참고할 수 있다.
시작하기 전에, 기술적인 부분은 2분정도로 짧게 다루어지지만, 이 중 한개의 스킬에서 이미 큰 시행착오를 겪은 경험이 있기 때문에 모든 과정을 구현하는 데에는 아마 시간이 오래 걸릴 것으로 생각된다.
영상 작성자가 보여준 완성작은 소설 내 아마데우스와 본질적으로 크게 다르지 않을까 생각된다. 소설의 아마데우스는 인간의 기억으로부터 학습된 언어모델이고, 영상 제작자의 아마데우스는 게임 등장인물의 모든 음성파일 대본 즉 일부 생활패턴을 학습시킨 언어모델이다. 음성인식 기능 그리고 현재 OpenAI에서는 지원하지 않는 GPT로부터의 대화 시작 등 몇 가지 요소가 더 마련되면 더 소설 속의 아마데우스와 가까워질 것이다.
2. (중장기 프로젝트)Unity를 사용한, 미디 파일로부터 바운스 볼 자동 생성 시뮬레이터
매번 실행을 할 때마다 유니티 물리엔진이 큰 오차를 내지 않는다는 것을 확인했다. 그렇기 때문에 한번 배치가 완료된다면 미디 파일이나 타임스케일, 공의 시작지점 등을 바꾸지 않는 이상 계속 활용이 가능하다.
개발 환경의 플레이 도중 상태에서 생성된 오브젝트는, 프리펩으로 저장하면 게임을 정지해도 남겨둘 수 있다는 것을 알았다. 알고리즘을 통해 배치한 벽돌은 프리펩으로 저장하여 남길 것이다.
미디파일을 필요한대로 다루는 방법을 아직 찾지 못했다. 앞으로의 진척 과제이다.
기본적인 틀이 잡히면, 디자인적 요소를 더 신경쓰며 보완 해 나가야 할 것이다.
이상의 내용은 하나의 탬플릿으로 사용하여, 다양한 미디와 그에 맞는 스타일링을 거친 후 각각 영상 미디어로 가공 할 예정이다. 완료한다면 유튜브에 업로드 하지 않을까
3. GPT 둘의 상호 대화 구현
지금 환경에서도 사람이 직접 GPT 모델 두개를 놓고 수동으로 입력을 시켜주어 양방향 대화를 이어줄 수 있기는 하다.
셀레니움을 활용하여 이를 자동화 시켜줄 수 있을지, 프로젝트의 진척을 서로 보완해가며 사람의 도움 없이 괜찮은 결과물을 만들 수 있을지 궁금하다. OpenAI ChatGPT에는 입력해줄 수 있는 내용의 종류가 한정적이기 때문에, 처음에 어떤 프로젝트를 쥐여줄지도 고민해 봐야겠다.
4. NovelAI 자동생성 및 업로드
노벨AI를 매달 25달러를 주고 구독하고 있는데, 그럴싸한 아웃풋이 없어 아쉽기때문에, 셀레니움을 이용한 자동생성과 어딘가의 플랫폼에 업로드 하는 것을 자동화하는 프로그램을 짜 보고 싶다고 생각했다.
개발자도구의 콘솔창에서 쉽게 일러스트의 자동생성은 할 수 있었기 때문에, 셀레니움에서 콘솔창 제어를 활용 할 수 있을지 확인해 보고 싶다. AI그림을 대량으로 업로드할 플랫폼이 있을지도 찾아봐야겠다.
당장 확인한 내용은, DemoScene에서 제공하는 DemoScript를 그대로 사용하면 미디파일을 재생하며 콘솔에 음계를 로그로 보여주는데, 음계 로그와 동시에 오브젝트를 생성하려고 시도하면 오브젝트 생성은 메인 스레드에서만 가능하다는 에러를 보여주는걸로 보아 제대로 활용하기 위해선 다른 접근 방법을 생각해야 할 것 같다.
또한 자세히는 모르겠지만, 미디재생을 위해 할당받은 오디오 출력 채널을 도중 에러로 인해 Release 작업 없이 종료되면 오디오 채널이 계속 점유중인 채로 남게 되어 프로그램을 껐다 켜야하는 수고가 필요했다. 다른 방법이 있을 것 같긴 한데 초심자라 잘 모르겠다. 그리고 그 외 여러가지 테스트를 해 보며 충돌이 나 유니티가 종료되는 일이 굉장히 빈번했다.
I only plans to use Unity Ads(Unity Ads만 사용할 계획입니다) 선택 후 다음
My app is not live in an app store yet(내 앱이 아직 앱 스토어에 게시되지 않았습니다) 선택 후 프로젝트 추가
본인의 경우 에러 발생 창 나왔지만, Retry 버튼 클릭하면 바로 해결.
아까 보였던 광고 활성화 버튼이 사라져있으면 OK
Unity Ads Monetization 페이지에서 계속 진행. 설정 가이드 진입.
가이드에 따라 3개 스텝을 진행.
Install Unity Ads SDK(Unity 광고 SDK 설치)
개발환경의 Unity로 이동
Window > General > Services 진입하여, Advertisement Legacy 설치
또한 별개로 Setup Guide 페이지에서 Read integration guide 를 클릭하면 전체 가이드 공식문서가 열리며, 추후 사용할 예시 스크립트도 모두 여기에 적혀있다.
Testing(테스트)
실제 광고가 아닌 테스트 광고를 사용하기 위해 필요한 절차
Go to Testing 클릭하여 설정 페이지로 이동
Apple App Store 와 Google Play Store 의 편집 버튼을 눌러 Override client test mode 에 체크 한 후, Force test mode ON (i.e. use test ads) for all devices 을 선택하여 모든 장치에서 테스트용 광고를 사용하도록 설정한다.
추후 실제 광고를 사용하게 된다면 여기서 다시 설정을 바꿔준다.
Configure Ad Units(광고 단위 구성)
어떤 탬플릿의 광고를 사용할지 확인하기 위한 목적.
Go to Ad Units 버튼 또는 왼쪽의 광고 단위 탭에 접근한다.
여기서 확인해야 할 것은 상단에 표시된 iOS 게임 ID, 안드로이드 게임 ID 그리고 하단에 나온 광고 단위 ID 이다. 필요에 따라 다른 모양의 광고를 사용하면 되며, 예시로 전면 광고 ID인 Interstitial_Android와 Interstitial_iOS를 사용 해 보겠다.
광고 적용
앱 시작 시 ‘SDK 초기화’를 필수적으로 해야하며, 이후 필요한만큼 ‘광고 유닛 표시’ 를 한다.
SDK 초기화를 위해 씬에 빈 오브젝트를 하나 생성하여 아래 스크립트를 적용한다. 게임 시작 시 함께 실행된다. _androidGameId 변수와 _iOSGameId 는 5-c-iii에서 확인한 것을 기재한다.
AdsInitializer.cs(포스트 하단)
전면, 보상형, 배너 타입의 광고 중에 전면 광고를 넣어보자. 각 타입의 구현은 [공식문서]에서 확인할 수 있다. 아래와 같은 스크립트를 방금 생성한 오브젝트에 함께 적용한다. 게임이 시작되고 약 2초 후에 광고의 로드와 표시를 한다. _androidAdUnitId 와 _iOsAdUnitId 에는 각각 안드로이드와 iOS에서 표시될 광고의 타입(유닛)을 넣어주면 되는데, 전면광고를 예로 들면 각각 "Interstitial_Android” 와 “Interstitial_iOS”를 입력 해 주어야 한다. 광고 단위의 ID는 5-c-iii 과정에서 확인한 광고 단위 탭에서 확인 가능하다.
티스토리 이미지 위치 조정도 안되고, 오더리스트 타입도 설정 안 되고, 들여쓰기 내어쓰기도 안보이고, 코드블럭도 배치 안되고, 글씨 size 설정도 안보이고, 마크다운모드 다녀오면 글 전체 문단 배치가 박살나있고 왜 이러는지 모르겠다. 플랫폼 바꿔야할까 생각중
(소스코드)
// AdsInitializer.cs
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener
{
[SerializeField] string _androidGameId;
[SerializeField] string _iOSGameId;
[SerializeField] bool _testMode = true;
private string _gameId;
void Awake()
{
InitializeAds();
}
public void InitializeAds()
{
#if UNITY_IOS
_gameId = _iOSGameId;
#elif UNITY_ANDROID
_gameId = _androidGameId;
#elif UNITY_EDITOR
_gameId = _androidGameId; //Only for testing the functionality in the Editor
#endif
if (!Advertisement.isInitialized && Advertisement.isSupported)
{
Advertisement.Initialize(_gameId, _testMode, this);
}
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
}
// InterstitialAdExample
using UnityEngine;
using UnityEngine.Advertisements;
public class InterstitialAdExample : MonoBehaviour, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] string _androidAdUnitId = "Interstitial_Android";
[SerializeField] string _iOsAdUnitId = "Interstitial_iOS";
string _adUnitId;
void Awake()
{
// Get the Ad Unit ID for the current platform:
_adUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOsAdUnitId
: _androidAdUnitId;
}
void Start()
{
// 2초 후에 광고를 표시합니다
Invoke("InvokeAd", 2.0f);
}
void InvokeAd()
{
LoadAd();
ShowAd();
}
// Load content to the Ad Unit:
public void LoadAd()
{
// IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled in a different script).
Debug.Log("Loading Ad: " + _adUnitId);
Advertisement.Load(_adUnitId, this);
}
// Show the loaded content in the Ad Unit:
public void ShowAd()
{
// Note that if the ad content wasn't previously loaded, this method will fail
Debug.Log("Showing Ad: " + _adUnitId);
Advertisement.Show(_adUnitId, this);
}
// Implement Load Listener and Show Listener interface methods:
public void OnUnityAdsAdLoaded(string adUnitId)
{
// Optionally execute code if the Ad Unit successfully loads content.
}
public void OnUnityAdsFailedToLoad(string _adUnitId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error loading Ad Unit: {_adUnitId} - {error.ToString()} - {message}");
// Optionally execute code if the Ad Unit fails to load, such as attempting to try again.
}
public void OnUnityAdsShowFailure(string _adUnitId, UnityAdsShowError error, string message)
{
Debug.Log($"Error showing Ad Unit {_adUnitId}: {error.ToString()} - {message}");
// Optionally execute code if the Ad Unit fails to show, such as loading another ad.
}
public void OnUnityAdsShowStart(string _adUnitId) { }
public void OnUnityAdsShowClick(string _adUnitId) { }
public void OnUnityAdsShowComplete(string _adUnitId, UnityAdsShowCompletionState showCompletionState) { }
}
최근 유튜브에서 본 것들 중 인상에 남는 컨텐츠를 몇 개 가져왔다. 직접 플레이하는 게임이라기보다 디자인적 요소가 메인이 되는 내용이다. 2번 레퍼런스는 당장 시작해보아도 좋을 것 같다. bouncing square은 설명란에 소스를 공개해놓은 채널도 있었는데, 그 크리에이터들은 python을 사용했다.
해당 트랙의 사전캠프는 C# 프로그래밍의 기초(Unity와는 별개) 학습 문서와, 다섯개의 유니티 프로젝트 강의가 준비되어있다. 지금도 트랙 수강자가 계속 합류하고 있고, 모집 기간은 아직 남아있지만 거의 정원이 다 찼다는 듯
5회분의 유니티 프로젝트는 각각 n주차 프로젝트 라고 하여, 개개인이 시간 배분을 하여 약 5주간의 사전캠프에 모두 학습하는 것을 목표로 한다.
C# 학습과 유니티 프로젝트 1주차와 2주차
2023.11.30(목)
나는 저번주 목요일에 합류하여 일주일을 진행하였다. 생각해보니 C#은 이전에 따로 배운 기억이 없는데 유니티를 몇 차례 다뤄봤던 경험이 있어서 거의 아는 내용이었고, 변수값을 초기화 시켜놓지 않으면 기본적으로 어떤 값을 가지는지 등 디테일한 느낌의 요소들을 주로 알아갔다.
프로젝트는 저번 포스팅에도 작성했듯이 준비된 강의량이 엄청 많은 것은 아니다. 처음 유니티를 하는 사람이나 늦게 합류한 사람도 어렵지 않게 모두 커버 가능할 정도로 보였다. 내일배움캠프 진도 시트가 마련되어 있는데, 이미 마지막 주 프로젝트까지 끝낸 사람도 몇 명 보였다. 나는 오늘 2주차까지 진행해두고, 다른 작업이나 과거 프로젝트 코드개선을 하기도 했다.
생각했던 것과 달리 1주차 때 얻어간게 많았다. 지금까지 유니티를 야매로 배우며 건드리기 꺼려졌던 것들이 꽤나 있었기 때문(애니메이션과 UI전반). 대부분 기억을 되살려가며 익숙해져가는 느낌으로, '하늘에서 떨어지는 오브젝트를 먹으면 점수를 얻는 게임'을 작성했다. 그리고 과거에는 GameManager와 그 스크립트에 대해서 잘 모르고 정말 되는대로 사용했었는데 이 부분도 어떤 탬플릿이 좋을지 고민 해 가야겠다.
2주차 프로젝트도 1주차와 비슷한 느낌의 게임으로, '하늘에서 계속해서 떨어지는 오브젝트(square)들을 유저가 마우스 컨트롤(마우스커서=shield)로 잘 비벼서, 화면 하단의 특정 오브젝트(balloon)와 접촉하지 않도록 오래 버티는 게임'이다. 새로 학습한 스킬은 아래와 같다.
- balloon은 평소의 idle 상태와 접촉해서 터질 때의 die 상태, 두 가지의 애니메이션이 있고, 애니메이션 컨트롤러 라는 것을 사용하여 특정 상태에 따라 다른 애니메이션을 취하도록 하는 방법
- PlayerPrefs 클래스(맞나?)를 사용하여 게임이 종료되어도 점수 등의 데이터를 남기고 불러오는 방법
(1, 2주차 결과 이미지를 같은 라인에 나란히 두고 싶었는데 티스토리 글작성에서 왠지 되지를 않는다)
1주차와 2주차는 비교적 쉬운 프로젝트였다고 하며, 3주차에는 본격적으로 레벨 시스템과 여러 씬을 다루는 프로젝트를 한다고 한다. 어제자로 이제 신경 쓸 다른 일들이 적어져서 사전캠프 진행에 속도가 붙을 것 같다.
그 외 특별한 이벤트
구글 폼을 통해 내일배움캠프에 궁금한 것을 질문하는 설문을 진행했었다. 오늘자 학습을 진행하다가, 오후 6시에 ZEP(메타버스 수업공간) 내 이벤트 필드에 모여 폼으로 모인 질문에 답변하며 매니저님들과 소통하는 시간을 가졌다.
캠프 진행에 크게 중요한 내용은 보통 공지에 있는 편이기에 비교적 가벼운 내용이 많았고, 예전 OT때도 느꼈던건데, 매니저님의 밈 이해도나 엔터테이닝 능력이 저세상급이다. 'ㅁ 붕 쿤!' 자세를 실제로 카메라 앞에서 하는 사람을 처음 봤다. 드립학원이나 밈 학원이 정말 존재하는 게 아닐까.
캠프는 내가 생각했던것보다 훨씬 체계적이고 관리도 게을리 하지 않을 것 같은 인상을 받았다는 것이다. 그리고 진행 중 정기적인 평가도 이루어지고 이를 반영한 수강생의 역량에 따라 세개의 반이 운영된다고 한다. 이건 꽤나 경쟁심을 부추기는 좋은 요소라고 생각했다. 그래도 각 반에서 진행되는 특강들은 다시보기를 진행한다고 하니 불이익이라고 할 것은 없다.
그리고 TIL이라는 용어를 처음 알았는데, 'Today I Learned'의 약자로 특별한 건 없고 하루 배운 것을 정리하는 것이다. TIL은 캠프를 하며 반드시 작성을 시킨다고 한다. 내 경우는 블로그에 매 1회차만 작성하고 그만두는 경우가 대부분이었기 때문에, 외부의 시선을 느끼며 작성하는 것이 도움이 될 것이다. 이렇게 작성된 TIL은 복습에도 사용되고, 취업활동 때 성실성을 보여주는 근거로도 활용할 수 있을 것이다.
조금 찾아보니 지금 먼저 캠프를 하는 다른 수강생의 TIL을 살펴볼 수 있었다. 매일 그날의 기록을 적기 위해 프로젝트에서 캡쳐를 하는 것은 상당히 피곤한 일이다. 글 작성에도 시간을 소모한다. 나의 경우는 '정제된 내용을 게시하는 것'의 우선순위가 높을 것 같기 때문에 과연 매일 어떤 식으로 글을 작성해나갈지 아직 감이 잡히지 않는다. 미래에 읽어도 가독성이 좋은 글을 쓰고싶다.
적성검사는 잘 봤다고 생각했고, 에세이는 누가봐도 처음 보는 템플릿일 정도로 처참했다. 농담이 아니고, 어쩌다 하루 마음을 고쳐먹었지만 징징대는 베짱이가 써 본 시의 느낌이다. 오후 3시 7분 결과를 확인하라는 문자를 받고 벌써 결과가 나왔나 생각하며 싸피 홈페이지에 접속해보았다.
나도 믿지 못할 합격이라는 결과가 나왔다. 에세이에 자신이 없는 사람이라면 적성테스트에서 만점을 노려보면 좋을 것 같다는 비뚤어진 팁을 하나 남기고 싶다.
이왕 되었으니 있는 경험 없는 경험 모두 도전해보자 라고 생각했다. 인생에서 다시 찾아오기 힘들 기회임에는 확실하고, 역시 한차례 더 합격한다면 한차례 더 성장하는 기회를 얻을 수 있을 것임은 분명하다.
넥토리얼 준비를 할 때 처음 오픈카톡방을 찾아보았고, 오늘자로 두 번째 오픈채팅 검색은 SSAFY가 되었다. 많은 11기 준비생과 선배들이 면접스터디를 해 보는 것을 추천하는 분위기였기에, 바로 행동에 옮겼다. 지방에 살고 있기 때문에 온라인으로 할 수 있는 스터디를 찾아갔다.
면접 스터디
2023년 11월 29일(수)
첫 입장까지 할 숙제를 최대한 조사하여 노션 페이지에 담아갔다. 숙제 중 생전 처음 보는 토픽도 그렇고 들어보기만 했던 토픽에 대해서는 혼자 숙제를 하며 지식을 넓히는데에 도움이 되었다. 그러나 개인사정으로 스터디 열어주신 분께 양해를 구하고 스터디에서 하차하게 되었다.
내 상태와 별개로 면접 스터디는 어떻게든 확실히 서로를 보완할 수 있는 장이 될 수 있다는 것을 확실히 느꼈고 다들 정말 붙고 싶어하는 분위기도 도움이 되기 때문에 인터뷰를 준비하는 사람들은 꼭 한번은 참여하면 좋겠다.
그리고 SSAFY에 대해 아는게 별로 없다면 오픈카톡에서 얻을 게 많다. 인터뷰 관련해서도 관련 꿀팁이나 정보가 정말 많았다. 오픈카톡에 미리 참여하여 당분간 눈치보면서 이것저것 주워먹자.
앞으로
이제 지금 시점에서 할 수 있는건, '내일배움캠프' 수료를 하는 것과 1인개발자 또는 중소기업 게임개발직 정도가 되겠다.
SSAFY의 비전공자(내 실수인지 비전공자로 지원이 되어버림) 적성진단과 에세이를 마친 후 결과를 기다리는 중이었다.
SSAFY의 테스트 관련해서 따로 포스팅을 하지 않았기에 지금 적어본다면. 적성검사는 수리 및 추론문제 파트와 Computational Thinking 파트로 나뉘어져 있었는데, 수리추론은 서른 문제인가 스무문제에서 세 문제 이외 모두 제대로 풀었고 Computational Thinking 파트는 그 존재와 문제유형을 테스트 당일에 알아 당황한 감이 없지 않지만 주어진 시간 꽉 채워서 아마 만점을 예상한다. 수리추론에서 못 푼 세 문제의 유형은 옛날 IQ 테스트에서 볼 법한 도형 규칙성 찾기(어느 정도의 시간이 걸릴지 예측 불가능하기에 바로 포기했다), 하나는 시간이 부족해서 풀지 못한 경우의 수 문제이다.
아마 테스트의 성적은 나름 좋게 나올 것 같은데 역시 웹개발보다는 게임개발을 하고 싶다고 다시 생각하여, SSAFY에 제출할 에세이는 잔잔한 미친 시인이 되어 내 공허한 서사를 풀어냈기 때문에 아마 불합격 통지를 받는다면 에세이가 한 몫 하지 않을까 생각한다.
+ 인터뷰 대상자로 합격했지만, 인터뷰 대비 1일차에 아무래도 나한테 부족한 점이 많고 적성도 아닌 것 같아 길게 끌지 않고 하차하기로 결정했다.
2023년 11월 22일 수요일, 오후에 카페에 나가 SSAFY의 소식을 기다리며(과거 기수의 기록을 보면 11월 28일 쯤 발표 할 것으로 예상) 생각해두었던 내일배움캠프 게임개발 과정에 지원하겠다고 생각하며 바로 신청을 넣었다. 여기 지원한 데에는 몇 가지 이유가 있는데,
- 온라인으로 진행. / 다른 지방 부트캠프가 괜찮다 싶어 지원했다가 이거 때문에 방까지 구하는 것은 좀 아닌 것 같아 취소했고, 기숙사를 지원해주는 곳도 있었는데, 4인 1실에 부실한 시설(개인 데스크탑도 놓을 수 없어 보이는 환경)을 보고 실망하여 지원을 하지 않은 곳도 있다. 수도권에 살았다면 더 많은 곳에 지원하고 더 많은 채용모집에도 지원 해 볼 수 있었을텐데, 지방러의 고충이다.
- 팀 활동. / 팀 프로젝트를 하는지까지는 조사해보지 않았지만 일단 함께 팀원으로 할 수 있는 사람이 있다는 것에 의미를 가졌다. 여태껏 혼자 해왔기에 나 이외의 사람과 소통하는 경험이 필요하다.
- 튜터 활동으로 보이는 스크린샷에 마음이 쏠렸음. / 담임 매니저 집중 관리 라는 키워드로 Zoom 비슷한 환경에서 게임 개발 실습을 진행하는 사진이다. 어떤 환경에서 캠프가 진행되는지 살짝이나마 알 수 있었다는 점에서 마음이 기울었을지도.
- 'Unity 전액 국비지원 🔥단 선착순 50명 한정' 라는 문구에 급하게 지원함. / 낚였을지도 모른다(ㅎㅎ). 실제로 현재 사전교육생 수는 이것보다 많아보이는데 아직 정식으로 시작한건 아니기 때문에 모른다. 정말 선착순이라면 설마 짤릴지도?
+ (위에 대한 추가 내용) 모집 기간이 많이 남아있었지만, 정원 마감이 되었다. 늦게 합류하신 분들은 아쉽지만 예비 인원으로 본강의가 시작되기 전 까지 이탈자가 생기면 그 자리를 채운다는 듯 하다.
아무튼 이런저런 이유로 내일배움캠프(스파르타 코딩클럽) 유니티 게임개발 파트로 지원했다.
3일 이내에 결과가 통지된다고 했는데, 당일 저녁에 합격 발표(좀 애매하게 메시지가 와서 불합격 여지가 있는건지 알 수 없었다)를 받고 바로 슬랙 서버에 초대되었다. 아무래도 SSAFY 결과는 나오나마나가 된 것 같다.
2023년 11월 23일 목요일, 오후 3시 경에 연락을 받아 사전캠프에 합류하였다. 월요일에 이미 OT를 하고 사전캠프를 시작했다는 듯. 정해진 시간에 메타버스 플랫폼 ZEP에 접속하고 출석페이지에서 입실 버튼을 누르고 자습을 하는 시스템이다. 주어진 자료를 통해 공부하며 진도표에 체크를 해나간다. 교육 개시인 12월 21일 전까지는 계속 이렇게 진행하는 듯 싶다.
C#의 기초에 관한 자료와, 사전교육 5주에 걸친 Unity에 관한 교육 내용이 준비되어있는 것을 얼추 확인했다. C#의 내용은 기초중의 기초로 적은 분량이었기에 신경써서 메모할 내용은 없이 확인을 끝냈고, Unity 강의는 영상자료의 총 합 길이가 그렇게 길지 않은 것으로 보아 프로젝트 위주의 진행을 할 것 같아보인다.
뭔가 대한민국의 '메타버스' 이미지를 쏙 갖다놓은 메타버스 플랫폼을 처음 접해보고 새로운 기분을 느끼며 중간합류 한 첫주차 사전캠프를 보냈다.