Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

게임을 만듭니다.

개발일기 - 버그들 본문

old_Doona Rebirth

개발일기 - 버그들

인카고 2018. 4. 5. 06:52

오늘은 '두나 리버스'의 버그 이야기를 해봐야 겠네요. 앞으로도 계속 버그가 생산될테니 그 글들의 시작이라고 보시면 될 것 같습니다.


우선 버그리스트를 작성해보죠.

  1. 잘못된 위치 참조
  2. 메모리 누수
  3. OnApplicationFocus 관련
하나씩 간단하게 설명을 해 보겠습니다.


- 잘못된 위치 참조


'두나리버스'는 격자형태로 나누어진 맵 위에서 유닛간의 이동이 이루어집니다. 

제가 임의로 정의한 구조체인 MapNode(x, y)기반으로 위치가 정해지며 최종적으로는 월드스페이스 위치로 변경되어 게임오비젝트를 이동시키거나 스폰합니다.

건물이 부서지면 연기 이펙트가 약 3초후에 스폰되도록 코루틴을 이용해 코드를 작성하였습니다.

애니메이션상으로 3초정도 건물이 내려앉는 모습을 만들고 부서지기 시작할때 코루틴을 이용해서 '3초 후에 건물이 다 부서질꺼니깐 그때 연기를 스폰하렴'이라는 로직을 만든겁니다. 그런데 2초후에 스테이지가 전환되어 맵이 바뀌어 버린다면? 맵이 바뀌어서 가로로 길쭉한 맵이 새로로 길쭉한 맵으로 바뀌고 연기가 스폰해야 할 지점은 더이상 맵 위의 공간이 아니라면?



요런식으로 에러가 빡 나게됩니다.


- 에러가 나지 않으려면?


스테이지가 전환될때 게임오브젝트(건물 포함)들이 모두 파괴되고 코루틴의 주체인 오브젝트가 파괴되니 코루틴의 실행이 멈출겁니다.

하지만 '두나 리버스'에서는 유닛, 건물, 아이템 등 거의 모든 오브젝트를 오브젝트 풀로 관리하고 있습니다. 따라서 오브젝트 풀로 되돌아갈때

유니티에서는 게임오브젝트가 비활성화 될때 OnDisable함수를 실행시키니 이 함수안에서 코루틴을 멈추는 StopCoroutine을 실행해 주면됩니다.

물론 기존에 실행했던 코루틴에 대한 레퍼런스는 로컬변수로 가지고 있어야겠죠.


그냥 오브젝트 풀을 사용하지 않는것은 어떨까요? 실시간으로 수많은 오브젝트를 생성해야할 필요가 있는 게임이 아니라면 오브젝트풀을 사용하지 않음으로서 이러한 잡다한 관리의 걱정에서 해방될 수 있습니다. 결과가 이상하네요. 왠만하면 오브젝트 풀 쓰세요...(???)



- 메모리 누수


결론적으로는 '메모리 누수'라고 말 할 수 있지만 처음에는 '게임이 그냥 꺼버리는 증상'으로 명명된 버그였습니다.

게임을 실행해 놓은 상태로 오랜 시간 방치해두면(저의 테스트 기기상으로는 약 1시간) 게임이 종료되버립니다.

게임이 그냥 종료되 버리니 인게임 콘솔로 버그의 원인을 잡기도 어려웠습니다. 원인은 몰랐지만 '메모리 누수'를 의심하고는 있었습니다.

코드상에 자동으로 종료되게 해 놓은 부분은 없고 또 일정시간이 지난 후에야 일어나는 버그였기 때문이죠.

이때 큰 도움이 된것이 유니티의 '프로파일러'기능입니다. 이 프로파일러는 유니티 에디터로 실행중인 것도 프로파일링 할 수 있지만 USB로 연결된 기기에서 실행되는 게임도 프로파일링이 가능합니다. 

https://docs.unity3d.com/kr/current/Manual/ProfilerWindow.html

이 프로파일러에서 메모리 부분을 살펴본 결과 스테이지가 전환될때 텍스쳐와 메터리엘이 사용하는 메모리의 양이 계단씩으로 증가하는것을 확인할 수 있었습니다.

'두나 리버스'에서는 각 유닛의 피부색 입고있는 옷에따라 텍스쳐를 생성하여 그것을 사용하고 있습니다.

메 스테이지마다 텍스쳐를 생산하고 그 텍스쳐를 메모리에서 해제시키는 코드가 없기에 메모리 사용량이 계속 증가하고 있었던거죠(메터리얼도 대동소이)

그렇다면 해결방법은 두가지

1.스테이지가 전환될 때 적절하게 메모리상에서 지워준다.

2.특정조건(피부색, 옷색 등)에 따른 텍스쳐를 생산하고 그것을 관리하는 매니져를 만들어서 동일한 경우에는 이미 생성해놓은 텍스쳐를 사용한다.

저는 2번을 선택했습니다. 처음엔 1번을 중심으로 알아봤는데 C#에서 수동으로 메모리 관리하는것에 대해 이해가 부족해서 원하는 바를 이루지 못했습니다.

결국 스테이지가 몇번 바뀌다보면 메모리 증가량은 거의 사라지게 되고 테스트 결과 해당 증상은 사라졌습니다.



- OnApplicationFocus 관련


이건 정말 간단한 버그였습니다.

'두나 리버스'의 API를 만드는 과정에서 이런저런 인증 로직을 실험했었습니다. 그중에 장시간 어플리케이션에서 빠져나왔다가 다시 어플리케이션을 실행하는 경우 'OnApplicationFocus'함수안에서 스플레시 스크린으로 보내는 로직을 넣어놨습니다.

유니티광고를 볼때 OnApplicationFocus함수가 작동합니다. 게임을 하다가 최초인증시각이 현재시간으로부터 특정시간 흘렀고 OnApplicationFocus에서 파라미터를 true로 받았을 때 스플레시 스크린으로 보내버리는 현상이 나타났죠.

사실 이건 완전한 실수여서 공유해봤자 큰 도움은 안되겠네요. 아! 이 버그를 잡는데는 로그캣을 이용했습니다.

테스트 디바이스를 USB로 컴퓨터에 연결하고 두개의 로그캣을 띄워 하나는 유니티 로그만 볼수있게 필터링 했습니다.

http://citynetc.tistory.com/188



앞으로도 간간히 버그 소식(?) 전하겠습니다. 

'old_Doona Rebirth' 카테고리의 다른 글

개발일기 - 로비신 완성  (1) 2018.04.11
개발일기 - 로비를 활기차게  (0) 2018.04.06
개발일기 - 로비를 만들자  (0) 2018.04.02
여전히 게임을 만들고 있습니다.  (0) 2017.12.10
작업 진행상황....  (0) 2017.07.23
Comments