[Unity] 점수를 추가해 보자

PublicMinsu·2024년 8월 18일
0

개요

출처 : https://www.netflix.com/kr/title/81019087

게임마다 다르지만, 보통의 게임들은 점수가 존재합니다.
특히 오락실 게임의 경우에는 순위권 안에 들면 3글자를 남길 수 있는 권한을 주었죠.

그렇기에 게임을 소재로 하는 대중매체에선 점수와 관련된 요소를 많이 넣습니다.

예시로 게임 애니메이션인 '버그사냥꾼 글리치 테크'의 1화 내용은 점수로 경쟁하는 게임 대회에 참가하는 내용으로 이루어져 있습니다.

게임 다큐멘터리인 하이 스코어는 고득점의 영문명입니다.

레트로 게임과 관련한 만화인 하이스코어 걸 또한 제목을 점수와 연관하여지었습니다.

원래 점수를 넣기로 예정하였기에 이번 글에서는 점수를 간단하게 구현하고자 합니다.

점수 관리

게임 내에서 점수를 관리하는 방법으론 여러 방법이 있을 것입니다.

캐릭터마다 점수를 가질 수도 있고 스테이지마다 점수를 가질 수도 있습니다. 이러한 부분은 기획에 따라 다를 겁니다.

저는 고전 오락실 게임처럼 전역적으로 하나의 점수만 가지고 있고 플레이할 때마다 초기화되는 형식을 구현하고자 합니다.

전역적으로 하나의 점수를 관리한다는 점에서 싱글톤을 사용하는 방법이 떠올랐지만, 이번 프로젝트에서는 대도록 싱글톤을 회피하고자 하였기에 다른 방법을 생각해 봤습니다.

Scriptable Object

출처 : https://docs.unity3d.com/kr/2023.2/Manual/class-ScriptableObject.html

스크립터블 오브젝트를 사용하여 점수를 관리하고자 합니다.

스크립터블 오브젝트는 하나의 데이터를 여러 곳에서 참조할 때 유용한 데이터 컨테이너입니다.

스크립터블 오브젝트의 대표적인 장점은 메모리 사용량을 줄여주는 것입니다. 메모리 사용량이 줄어드는 이유는 스크립터블 오브젝트를 사용할 시 하나의 공통된 값을 참조하는 형식이기에 오브젝트마다 값의 사본을 만들 필요가 없기 때문입니다.

(여담으로 스크립터블 오브젝트와 싱글톤을 합친 형태도 존재합니다.)

메모리 테스트

실제로 언급한 대로 메모리 소비를 줄여주는지 궁금했습니다.
테스트를 위한 첫 번째 환경입니다. 20개의 Vector4를 선언해 줬습니다.

두 번째 환경입니다. Vector4는 스크립터블 오브젝트에 작성해 주고 오브젝트에 붙여줄 스크립트에는 스크립터블 오브젝트를 참조하게 하였습니다.

오브젝트 40개에 스크립트 40개를 붙이고 실험해 봤습니다.

메모리 프로파일러로 확인해 보면 두 번째 환경에서는 오브젝트마다 부착된 스크립트의 메모리가 줄어든 것을 확인할 수 있습니다.

확인해 본 결과 오브젝트가 공통된 값을 가지고 있다면 스크립터블 오브젝트로 관리해 주는 편이 메모리 효율적이라는 것을 알 수 있습니다.

데이터 에셋 만들기

ScriptableObject로 에셋 만들기

ScriptableObject를 사용하는 방법은 간단합니다.
ScriptableObject를 상속하는 클래스를 만들면 됩니다. ScriptableObject는 MonoBehaviour와 달리 Component를 상속하지 않았기에 GameObject에 붙일 수 없습니다.

그렇기에 사용하려면 에셋으로 만들어서 사용해야 합니다.

CreateAssetMenu를 사용하시면 프로젝트 창에서 에셋을 만들 수 있게 해줍니다.

프로젝트 창에서 마우스 오른쪽 클릭을 했을 시 나오는 Create에서 menuName에 적었던 경로가 생긴 것을 확인할 수 있습니다.

생성한 에셋은 MonoBehaviour와 동일하게 인스펙터에서 표시됩니다. MonoBehaviour와 동일하게 직렬화된 변수를 추가해 주면 인스펙터에 해당 변수를 표시해 줍니다.

만들어진 에셋을 사용하는 방법은 직렬화된 필드를 만든 뒤 해당 필드에 집어넣거나 스크립트에서 리소스를 불러와주면 됩니다.

코드 작성하기

데이터 에셋

점수를 관리할 에셋에 작성한 코드입니다.
점수를 설정하고 점수가 변경될 때 호출될 이벤트를 작성했습니다.

시간을 관리할 에셋에 작성한 코드입니다.
점수와 크게 다를 점은 없습니다만 점수와 달리 시간은 deltaTime만큼 늘어나게 하였습니다.

코드는 프로젝트 진행하는 동안 크고 작게 변할 수 있는 부분이니 일단은 이 정도로 작성하고 진행합니다.

게임에서 적용

데이터 에셋을 만들었다면 해당 데이터 에셋을 사용하는 곳에서 함수나 변수를 가져와서 사용하면 됩니다.

게임이 시작될 때 점수를 초기화해주고 시간이 지날 때마다 시간을 증가시키는 함수를 호출되게 했습니다.

이후 큐브가 범위를 벗어날 때마다 점수를 증가시키는 함수를 호출했습니다.

이로써 게임을 시작하면 점수와 시간 데이터는 초기화되고 점수와 시간 데이터는 각각 조건에 따라 갱신될 겁니다.

UI에서 적용

데이터가 준비됐으면 UI에서는 해당 데이터를 가져와서 적용하면 됩니다.

캔버스에 텍스트 UI를 배치하고 UI를 관리해 주는 스크립트를 추가합니다.

현재는 UI가 복잡하지 않기에 하나의 스크립트로 처리하고 있습니다.

데이터가 갱신되는 이벤트에 연결해 준 뒤 갱신되는 데이터를 가져와서 가공한 후 UI에 표시해 주었습니다. 지금 와서 생각해 보면 가공하는 과정은 데이터에서 하게 수정하여도 괜찮을 거 같다는 생각이 들기도 합니다.

점수를 적용한 화면

점수와 시간이 잘 작동하는 것을 볼 수 있습니다. 점수를 추가하고 나니 사라지는 큐브가 점수와 연관된다는 것을 플레이어가 눈치채기 어렵겠다는 것을 느끼게 됐습니다.

후기

Square Square Square 프로젝트는 반년 정도 손을 대지 못했습니다. 정확히 말하자면 조금씩 손을 대긴 했습니다만 글을 작성하거나 커밋을 하지는 않았습니다.

중간에 할 일이 생겼고 매일 알고리즘 문제 풀이를 하면서 병행하기에는 좀 힘들었습니다.

해당 글을 작성하려고 준비한 자료를 실수로 지웠다는 것을 눈치챘을 때는 고민을 많이 했습니다. 최근에 임시 글에 해당 작업을 백업해뒀었다는 사실을 기억해 냈고 덕분에 글을 마저 쓸 동력을 얻게 됐습니다.

Square Square Square 프로젝트에 대한 고민이 많습니다.
우선순위가 높은 프로젝트가 아니어서 질질 끌리고 있는데 대충 마무리하기에는 아쉽기도 합니다. 그렇다고 신경 쓰자니 다른 일이 우선됩니다. 그래서 지금처럼 가끔 시간이 남으면 조금씩 수정하면서 완성하지 않을까 싶습니다. (해당 프로젝트는 저 혼자만의 약속이니까요)

profile
연락 : publicminsu@naver.com

0개의 댓글