안 쓰던 블로그

[유니티] Prefab의 역할에 대한 생각 본문

유니티/개발

[유니티] Prefab의 역할에 대한 생각

proqk 2021. 8. 4. 22:14
반응형

 

https://play.google.com/store/apps/details?id=com.YujinLee.PicturePuzzle 

 

솜이랑 한글 공부 - Google Play 앱

귀여운 강아지 '솜이'와 재미있는 한글 공부!

play.google.com

 

위에는 내가 개발하고 있는 한글 공부 앱 <솜이랑 한글 공부>의 모습이다.

 

이번에 "음절 맞추기" 기능을 추가하면서 여러 가지 문제를 만났었다.

이제까지(2.7버전까지) 개발하면서는, '넣고 싶은 기능이 있는데, 어떻게 구현할지 몰라서' 고민했다면, 이번 개발(3.0버전) 때는 '기능을 넣었고 에러 메시지가 뜨지 않는데 원하는 동작을 하지 않아서' 고민을 했다.

 

나는 2019년 겨울에 잠깐 배운 유니티를 가지고 필요한 것이 있을 때마다 검색하며 개발을 해 왔다.

특히 이번 업데이트를 하며 마치 도로의 모든 신호등에 한 번씩 멈추고 가는 듯 여러 문제를 맞닥뜨리며, 유니티 기본 지식이 부족함을 많이 느꼈다.

 

이번에 마주한 대부분의 문제는 Prefab (이하 프리팹)이 원인이었다.

문제를 해결하며 든 생각을 정리한다.

 

Prefab

Prefab, 프리팹이란 무엇인가? 유니티 공식 매뉴얼에서는 프리팹을 '재사용 가능한 에셋이며, 씬에 새로운 프리팹 인스턴스를 만들기 위한 템플릿 역할을 한다'라고 설명한다.

프리팹을 사용하면 동일한 게임 오브젝트가 여러 개 필요할 때, 단순히 복사하는 것보다 더 효율적으로 게임 오브젝트를 생성할 수 있다.

'동일한 게임 오브젝트가 여러 개'라고 했지만 꼭 동일한 오브젝트가 아니어도 된다. 일부 인스턴스를 다르게 하고 싶다면 인스턴스 설정을 오버라이드하면 된다.

프리팹을 프리팹 배리에이션으로 그룹화할 수 있다는 특징도 장점이다.

또한 프리팹 원본만 수정하면 모든 프리팹에 자동으로 반영되므로, 게임 오브젝트 복사본을 하나씩 바꾸어주지 않아도 전체 프로젝트를 일괄적으로 변경이 가능하다.

씬에 존재하지 않은 게임 오브젝트를 런타임 시점에 인스턴스화하는 경우에도 프리팹을 사용한다.

 

프리팹은 보통 다음과 같은 상황에서 사용할 수 있다.

1. 여러 번 사용되는 특정 유형 (예: 환경을 꾸밀 때 나무, 수십 개의 스테이지 버튼)

2. 적, NPC 등 논플레이어 캐릭터 (예: 비슷한 유형의 적들을 오버라이드하여 생성)

3. 발사체 (예: 인스턴스화한 총알, 포탄 등)

 

Prefab에 대한 고찰

https://foxtrotin.tistory.com/509 

 

GridLayoutGroup에 소속된 오브젝트의 position 가져오기

LayoutGroup을 적용한 부모 오브젝트 아래로, Text Prefab를 Instantiate로 생성해서 자식 오브젝트로 넣는 방식으로 정렬시켰다 이 상황에서 자식으로 생성된 Clone들의 Position을 가져오고 싶은 상태 (위

foxtrotin.tistory.com

https://foxtrotin.tistory.com/510

 

Button Prefab에 Onclick() 추가하기!!!!

드디어!!!! 해내서!!!! 동작해서!!! 글로 기록합니다 원하는 것: Prefab로 만든 Button을 Instantiate로 생성한 뒤, 생성한 오브젝트에 OnClick 이벤트를 할당하고 싶다 Button Prefab는 현재 이런 상태 Box Mana..

foxtrotin.tistory.com

https://foxtrotin.tistory.com/512

 

Transform[] 의 Destroy 및 GetComponentsInChildren의 오브젝트 누적 문제와 해결 (초기화 에러)

원하는 것: 한 번의 게임 라운드가 끝나면, 사용했던 Transform[] 의 게임 오브젝트를 전체 Destroy 한다. 다음 라운드에서 Instantiate로 오브젝트를 생성한다. 생성한 오브젝트들의 Transform[]을 만들어서

foxtrotin.tistory.com

https://foxtrotin.tistory.com/513

 

Prefab으로 생성한 Button 오브젝트를 클릭할 때마다 효과음 재생하기

원하는 것: Prefab으로 만든 Button 오브젝트가 클릭될 때마다 딸깍하는 효과음을 재생한다. 실패: public void OnClickbox5() { clicksound.PlayOneShot(clicksound.clip); gm5.putAnswerText(me); } 처음에 짰..

foxtrotin.tistory.com

 

이 글들은 이번에 개발하면서 마주한 문제들을 정리한 글이다.

 

Prefab은 위에서 말했듯 '재사용 가능한 에셋'이다.

그리고 나는 Prefab을 '비슷한 동작을 하는 게임 오브젝트가 여러 개 필요할 때' 사용한다고 생각했다.

 

위의 글 중 세 번째 글인 <Prefab으로 생성한 Button 오브젝트 클릭할 때 효과음 재생하기>의 내용에도 있지만,

나는 [버튼을 누른다->누름을 감지한다->효과음을 출력한다] 라는 동일한 동작을 수행하는 버튼을 여러 개 생성해야 하는 이 상황이 프리팹의 역할 범위라고 생각해서, 프리팹에다가 Audio Source를 달고 Play()까지 시켰다. 그러나 그 프리팹을 여러 개 복사해서 게임 오브젝트로 만들고 나니 오류는 나지 않지만 정상 작동하지 않는 문제가 생겼다.

이 경우 Audio Source를 프리팹이 아닌 다른 오브젝트에 추가했더니 잘 작동되었다.

즉, [버튼을 누른다->누름을 감지] 까지만 프리팹의 역할이고, [효과음을 출력한다]는 다른 스크립트의 역할이었던 것이다.

 

좌표 문제, 값 누적 문제 등 이런저런 문제를 지나고 보니,

Prefab은 빈 껍데기만 있는 게임 오브젝트를 만들기 혹은 아주 간단한 동작(예: 총알이 앞으로 이동)만 커버하고, 나머지 행동에 대해서는 GameManager 등의 다른 스크립트가 오버라이딩이나 추가하는 식으로 사용하는 느낌이 아닐까 싶다.

 

Prefab가 생성되면 같은 게임 오브젝트이기는 하지만, 뭔가 행동을 하길 바라며 이것저것 추가하기에는 제약이 너무 많다.

또한 유니티 내부적으로 처리되는 계산이 복잡한 건지, 오브젝트 생성 순서나 계산 실행 순서 등에서 개발자가 의도한 것과 다른 동작을 할 때가 종종 발생한다. (내가 초보 개발자라서 그럴 수도 있지만..)

예를 들어 [전투기가 총알을 발사하고, 적 기체와 충돌하면 폭발 효과음]을 개발하는 상황에서 총알을 Prefab으로 만든다면, 총알은 [생성되면 적 기체로 이동한다]만 해야지, [생성되면 적 기체로 이동하고, 충돌 판정이 되면 폭발 효과음을 재생한다] 까지는 비추천이라는 말이다.

 

아무튼 결론은, Prefab을 사용하면서 생긴 문제들을 돌이켜보면 Prefab은 그렇게 복잡한 일을 담당하는 것이 아니라는 느낌을 받았다.

 

Prefab은 유니티 개발을 하며 빠질 수 없는 요소이므로, 이미 많은 사람들이 수없이 사용하고 있다.

분명히 내가 지금은 모르는 더 효율적인 방법 또는 문제를 일으키지 않고 적절하게 사용하는 방법들이 많이 있을 것이다.

고수 게임 개발자 분들은 이미 알고 계실 것 같다.

 

이 글은 내 개인적인 생각이므로 내용은 틀릴 수 있다.

반응형
Comments