목차
모든 글
[12] 코드 리팩토링 작업
맨땅 헤딩으로 게임 제작을 시작한지 약 한~두달,
초기에는 싱글톤패턴을 활용해서 제작을 해 보려고 했습니다. 하지만 이 싱글톤패턴에 대한 명확한 공부가 이뤄지지 않은 상태에서 정말 대강의 느낌만 이해한채로 하다보니 코드가 굉장히 기형적으로 변했습니다.
굳이 SAVEDATA에 들어가 있지 않아도 될 데이터가 들어가있는것은 기본이고, SAVEDATA는 미친듯한 단순 변수의 나열로만 이루어져있어서 데이터를 하나 변경하면 스크립트 파일 서너개의 값을 같이 바꿔줘야하는 수고는 물론에,
불필요한 코드의 중복이 상당히 많아짐을 느끼게 되어 고민끝에 코드를 한 번 싹 갈아엎자라고 생각했습니다.
조금씩 개발을 하다보니 익숙해지면서 조금 더 코드를 어떤 방향으로 짜야할지 감이 왔습니다.
물론, 정말 감만 왔습니다. 짜는건 또 다른 문제더라고요.
좌측이 전, 우측이 후 입니다.
싱글톤패턴을 잘 활용했어야하는데, 그러지 못하고 DataManager에 게임에 관련된 변수, Enum 모든걸 다 때려박아버려서 미친사태가 발생해버렸습니다.
그래서 우선 기존의 아무렇게나 쌓아올려진 데이터를 다시 필요한 부분으로 다 분류했습니다.
그리고 분야별로 적당히 클래스화해서 데이터를 조금 더 사용하기 쉽게 정리했습니다.
또한 실제 플레이에 사용되는 변수들의 경우에는 굳이 DataManager에 들어가서 save load 될 필요가 없기에 아예 게임플레이 관련된 Manager를 새로 파서 싱글톤으로 관리되게 해 주었습니다.
스테이지가 끝날때마다 스킬을 선택하는 씬으로 넘어가고 다시 스테이지 씬으로 넘어오는 그런 왔다갔다하는 일이 있는 게임이다 보니 그런식으로 관리하는것이 필요해 보였습니다.
대략 2~3일동안 꼬박 코드만 정리했었습니다.
근데, 막상 또 정리라고 해놓고 다시 보니까 영 이상하고 맘에 안들긴 했었다는게....
그래도 전보다는 좀 나아졌다고 생각하고 다음에 좀 더 공부해서 갈아엎으면 되지 않을까 싶습니다.
하지만, 코드를 고치고 실행을 해보았지만, 거기엔 오직... 오류뿐이었어.
그리고 이 오류를 고치고 실행가능하게 하는것에 또 하루를 사용하게 됩니다.
조금 고생을 하긴 했지만, 이렇게 부딪히다보니 또 이제 많은걸 배우게 되었습니다.
1. MonoBehaviour인 경우, 생성자를 사용하지 말고, Awake, Start 사용.
[당시 발생한 log]
unityexception: find is not allowed to be called from a monobehaviour constructor (or instance field initializer), call it in awake or start instead. called from monobehaviour 'gamemanager' on game object '@managers'. see "script serialization" page in the unity manual for further details.
아... 연장을 모르고 다루려고 하니 이런 사단이 발생했습니다.
그동안 MonoBehaviour이 있는것과 없는것의 차이를 크게 생각하지 않고 있었다가 이 문제로 인해서 또 아예 구조를 변경해야하다보니 공부를 하게 되었습니다.
https://forum.unity.com/threads/find-is-not-allowed-to-be-called-from-a-monobehavior.755675/
2. XML 사용시, 다른 클래스여도 같은 이름이 있으면 안된다?
[당시 발생한 log]
InvalidOperationException: Types 'Character.ID' and 'Active.ID' both use the XML type name, 'ID', from namespace
제가 문제를 정확히 작성한건지는 잘 모르겠네요.
하지만 비슷하게는 적은 것 같습니다.
기존에 액티브스킬, 패시브스킬, 캐릭터 종류 등등 여러가지를 Enum으로 관리했었습니다.
근데 이거를 이제 각기 다른 클래스화해서 정리해놓다보니 Enum 이름을 ID로 통합하면 편하지 않을까 해서
그렇게 했었는데요, 이렇게 하고 나니 XmlSerialization에 문제가 발생했습니다.
다른 클래스여도 안에 들어있는 이름이 같으면 같은걸로 인지를 하는건지 문제가 발생하더라고요.
이에 대한 해결법은 찾아봤는데 사실 아직도 Namespace를 사용해서 하는 방법이 잘 이해가 가지 않아서
위의 링크의 방법은 사용하지 못했고 근본적 원인인 이름의 동일을 다르게 바꾸는것으로 해결했습니다.
만드는데 여전히 급급해서 확실히 배우고 적용했어야 했을텐데 조금 후회가 남네요.
어찌되었든, 우선 바꾼 코드로 실행은 되도록 고쳤습니다.
그런데... 실제 게임 플레이에서 묘하게 프레임이 많이 떨어진다는 느낌을 받았습니다.
'Find'함수의 사용은 최대한 줄여라!
이 말은 정보를 얻으려고 구글링하다보면 꼭 한 번씩은 보게 되는 말이었기 때문에, 개인적으로는 최대한 Find를 줄인다고 생각하고 작업을 했었습니다.
Tag를 불러올때도 CompareTag를 사용하기도 하고요.
아 그런데, 코드 리팩토링을 하면서 저도 모르게 Find를 상당히 남발하게 됐었나봅니다.
중복된 코드를 줄인답시고 저기서 불러오고 여기서 불러오면서 문제가 발생한 것이지요.
이 문제를 어떻게 해결해야하나 싶어서, 처음 Start 함수에서 Find로 미리 필요한 것들을 다 찾아서 변수에 저장한 후, 불러오는 방법을 사용하면 처음에만 Find가 사용되고 이후 게임 진행에서는 Find가 발생하지 않으니 괜찮을듯 하여 이런 방식으로 코드를 개선했습니다.
그런데, 또 이렇게 하니 처음 시작부분에서 버벅임이 조금 생겼습니다...
비동기 로딩을 사용하자.
그래서 또 이 시작할때 렉을 어떻게 개선해야할까 고민했습니다.
아무래도 씬이 넘어가고 불러올거를 같이 불러오다보니 문제가 발생하는것 같으니
불러올 것을 다 불러오고 씬이 넘어가면 괜찮지 않을까 싶어서 이 쪽에 대해서 검색을 해 나가다보니 역시나
'비동기 로딩'이라는 해결책이 있었습니다.
바로 코드를 찾아보고 적용해 보니 플레이시 프레임이 상당히 쾌적해졌습니다!
제가 생각하기에 아직도 저희 게임은 여기저기서 메모리 낭비가 심하고 최적화가 안된 누더기 골렘이겠지만...
그래도 이렇게 코드를 갈아엎어보면서 많은것을 배우고, 최적화의 일면을 엿본 좋은 경험이었던것 같습니다.
아무래도 이번 프로젝트가 일단락 된다면, 기존의 좋은 코드를 참고하며 클론코딩을 해 보는 방향으로 공부를 해 봐야 할 것 같습니다. 어느정도 툴에도, C#에도 조금 익숙해졌으니까요.
[13] 화면비율을 16:9로 고정하다. 전반적인 리소스 추가.
초기에는 화면비율에 대해 알아보기는 했지만, 크게 고민을 하지는 않았습니다.
기종별로 어느정도 차이가 있는것 같은데 어느정도 비율별로 있는듯 하니 가장 큰 비율에 우선 맞춰서 만들면 알아서 기종별로 맞춰지지 않을까? 하는 그런 미친 안일한 생각이었던것이죠.
하지만, 태블릿도 지원하고 싶고 이래저래 생각을 하다보니
그럴거면 그냥 아예 화면 비를 고정시켜버리는것이 개발하는입장에서도 편리하고, 게임을 즐기는 유저 입장에서도 모든 기종에서 평등한 플레이 환경이 제공되니 좋은게 아닌가 라는 생각을 합니다.
그래서 어느 화면비가 제일 만만할까 싶어서 찾아보니 16:9가 괜찮지 않을까? 해서 그렇게 하게 됩니다.
문제는 대부분의 씬 UI 작업을 다 하고 생각했다는 것이죠.
그것도 3040 X 1440 이 비율로 작업을했었는데요...
하지만, 코드 리팩토링도 얼추 해 본 입장에서 이제 이정도 갈아엎음은 웃으면서 할 수 있습니다.
그리고 화면비를 다 바꿔버립니다.
물론 이 과정에서 몇몇 씬의 배경이 들어가고, UI버튼등도 새로 작업되어서 반영이 됩니다.
이전에 보여드렸던, 처참한 모습과는 꽤나 많이 달라졌다고 자부할 수 있습니다!
저번 개발일지 기준으로 전 후 비교를 해 드리겠습니다.
좌측이 전, 우측이 후 입니다.
1. 메인 화면
버튼부분의 수정이 이루어졌습니다.
난이도 선택시, 어떤 난이도로 선택이 되어있는지 버튼에 바로 표시가 됩니다.
2. (구)재능 (현)체질
저번 개발일지에서 소개시켜드렸던 '재능'(구) 씬입니다.
코드상으로는 큰 차이가 없고 정말 그래픽 리소스만 추가된 후 UI위치만 조금 이래저래 바뀌었습니다.
추가로 원하는 스탯을 클릭하면 주변에 후광?이 생기는 이펙트도 추가해봤습니다.
3. 캐릭터 선택 및 육성
완전히 싹 갈아엎었습니다 이 부분은.
처음 캐릭터 창에 들어서면 캐릭터 선택만 할 수 있도록 깔끔하게 정리했으며
캐릭터 스탯을 성장시키고 싶을 시, 좌측 상단의 육성을 누르면 족자가 펴지면서 성장 및 현재 스테이터스를 한눈에 볼 수 있도록 하였습니다. 이 스테이터스는 '재능'을 포함합니다.
4. 난이도 선택
난이도 부분을... 저번 개발일지 시점에서 이미 구현되어있었는데
깜박하고 소개를 못 드렸습니다.
난이도는 총 10단계로 되어있습니다.
이는 테마별로 10단계이기 때문에 추후 테마가 추가가 된다면 이제 게임의 난이도는 테마가 하나 늘어날때마다 10단계씩 늘어난다고 생각하시면 될 것 같습니다.
난이도의 이름은 이제 24절기 중 10가지를 따와서 지어줬습니다.
봄부터 시작해서 겨울까지 씨앗이 움트고 나뭇잎이 다 지는 것까지 자연을 통해 난이도를 표현했습니다.
5. 시작 전 구매 아이템
그나마 시작 전 구매 아이템 부분은 좀 변화가 덜하네요.
라고 저도 생각했었는데요, 이전 작업물을 살펴보다보니 저것보다 더 된 과거가 있었습니다.
ㅎㅎ... 정말 처참하네요.
6. 일시정지
일시정지창은 아예 개편을 했습니다.
일시정지를 하게 되면, 게임을 하면서 습득했던 패시브 아이템의 종류가 표시되는 방향으로 가닥을 잡았고
UI또한 전체적으로 다듬었습니다.
7. 스킬 선택창
스킬 선택창 또한 개선이 되었습니다.
상자를 클릭하면 스킬을 선택하는 것이고, 상자 위에는 해당 내용물? 인 스킬이 은은하게 떠다닙니다.
그 이미지를 클릭하면 해당 스킬에 대한 설명을 볼 수 있습니다.
8. 게임 엔딩씬
사실 추가가 됐다고 보는게 맞을것 같네요.
기존에는 게임이 클리어되는 조건도 없었고 체력이 다 소진되면 일종의 디버깅 목적으로 스테이터스만 나열했었는데
이번에는 임시로 점수 기준도 만들고 해서 클리어, 실패시 나오는 화면을 제작했습니다.
[14] 사운드 추가, MWU 지원
한창 개발하던 중에, MWU(Made With Unity) 공고를 보게 됩니다.
27일 오후 11시까지... 그 당시 저희에게 남은 기간은 약 일주일이었습니다.
어느정도 게임의 대략적인 틀은 완성되어 있었던 상태였고 출시가 안된 게임도 괜찮다는 것을 확인.
저희의 목표는 단 하나, 참가팀 전원 유니티 티셔츠 증정!
아무리 데모버전도 제출이 가능하다지만 어떻게든 좀 더 괜찮은 상태로 내고 싶어서 나름 꽤 열심히 작업하게 됩니다.
UI도 손보고 최대한 플레이 버그도 잡아보려 노력해보고... 사운드를 추가합니다...!
사운드의 경우에는 위의 영상에서 어떤 소리가 추가되었는지 확인 가능합니다!
그리고 마감 당일 아침날, 트레일러를 제출해야한다는 것을 모르고 있었던 저희팀은
그제서야 부랴부랴 급하게 트레일러도 만들어보게 됩니다.
만든 게임을 소개한다는게 참... 어렵다는걸 새삼 느끼게 되었던
얼렁뚱땅 MWU 지원일정이었습니다.
이것으로 이번 개발일지를 마치겠습니다!
이번 글은 굉장히 길었는데요, 실제로 저번 개발일지 시점이후로 개발 컨셉이 어느정도 가닥이 잡히고 하다보니
개발이 급 진전이 되어서 보여드릴 내용이 꽤 많았습니다.
MWU 제출시점까지 왔으니, 거의 지금 보이는 것이 현재 저희 게임 상태와 크게 다르지 않다 라고 보셔도 될 것 같네요.
지금은 저 이후에 또 뭔가 새로운 기능을 좀 넣고 싶어서 추가하고, 밸런스 및 테스트기간을 갖고 있는 중입니다.
너무나도 긴 글 클릭하고 봐 주셔서 감사합니다!
다음 개발일지로 뵙겠습니다!
[이전 글 보기]
'Unity3D > [유니티 인디게임] 처음 공부부터 출시까지' 카테고리의 다른 글
[유니티 인디게임] 처음 공부부터 출시까지. - 7(完) (2) | 2021.09.20 |
---|---|
[유니티 인디게임] 처음 공부부터 출시까지. - 6 (0) | 2021.09.08 |
[유니티 인디게임] 처음 공부부터 출시까지. - 4 (0) | 2021.09.02 |
[유니티 인디게임] 처음 공부부터 출시까지. - 3 (0) | 2021.08.31 |
[유니티 인디게임] 처음 공부부터 출시까지. - 2 (0) | 2021.08.30 |