[Unity] 유니티 프로젝트를 구성하기 위한 방법

JaehyeokSong0·2022년 12월 10일
0

Unity

목록 보기
1/1

BEST PRACTICES FOR ORGANIZING YOUR UNITY PROJECT를 번역 및 정리한 문서입니다. 개인적으로 정리한 문서이기 때문에 내용의 생략과 의역, 각색 등이 있으니 더욱 정확한 내용을 알기 위해서는 원문을 읽는 것을 추천드립니다.


폴더 구조

유니티 프로젝트를 구성하기 위한 방식에 정해진 것은 없지만, 더욱 효과적인 프로젝트 관리를 위해 권장되는 요소들은 있습니다.

  • 네이밍 컨벤션과 폴더 구조를 문서화하기
    스타일 가이드와 프로젝트의 템플릿은 파일의 위치나 구조를 결정하는 것을 쉽게 만듭니다.
    팀에 적합한 방식을 선택하고, 모두가 이에 찬성하는지 확인하세요.

  • 네이밍 컨벤션을 일관성 있게 유지하기
    선택한 스타일 가이드와 템플릿에 대한 일관성을 유지하세요.
    만약 이러한 규칙을 수정할 일이 있다면 이에 영향을 받은 모든 에셋의 이름을 재설정하고, 변경할 파일이 너무 많다면 스크립트를 이용하여 업데이트를 자동화하는 것을 고려하세요.

  • 파일과 폴더 이름에 공백 사용하지 않기
    유니티는 공백이 포함된 경로명을 처리하는데 적합하지 않습니다.
    공백을 사용하는 대신 camelCase를 사용하세요.

  • 테스트/샌드박스 영역을 분리하기
    테스트는 별도의 폴더 내에서 진행하세요.
    당신의 username을 이용한 하위 폴더를 이용하여 팀 멤버들과 작업 공간을 나눌 수 있습니다.

  • 루트 레벨에서 추가 폴더를 사용하지 않기
    일반적으로 컨텐츠 파일들은 Assets 폴더에 저장되어 관리됩니다.
    불가피한 경우가 아닌 이상 프로젝트의 루트 레벨에는 폴더를 생성하지 않습니다.

  • 내부 에셋을 서드파티 에셋과 분리하기
    에셋 스토어 혹은 타 플러그인으로부터 구한 서드파티 에셋은 자체적인 구조를 가질 가능성이 높기 때문에 내부 에셋과 분리하여 관리합니다.

Note: 서드파티 에셋이나 플러그인을 변경하여 사용해야 할 경우, 버전 컨트롤을 이용하여 당신의 수정사항으로부터 최신 업데이트 버전에서 변경된 점을 확인하고 이를 재구현할 수 있습니다.

정해진 폴더 구조는 없지만, 다음 두 섹션에서는 유니티 프로젝트를 구성하기 위한 예시들을 소개합니다. 이러한 구조들은 에셋의 종류별로 프로젝트를 분할하는 방식을 기반으로 합니다.


폴더 구조 예시 1


폴더 구조 예시 2


에셋 타입에 따른 하위 폴더


체계적인 프로젝트 구조를 설정하는 것은 추후에 있을 버전 컨트롤 이슈를 컨트롤하기 쉽게 만듭니다. 에셋을 다른 폴더로 이동하는 경우, 많은 버전 컨트롤 시스템은 이를 파일의 이동이 아닌 파일 제거와 생성으로 간주하여 파일의 히스토리를 잃게 될 가능성이 높습니다.

Plastic SCM을 통해서 유니티 내에서의 파일의 이동과 히스토리 보존 등을 관리할 수 있습니다. 하지만 에디터 내에서 파일을 이동해야 .meta 파일이 에셋과 함께 이동하므로 주의를 기울여야 합니다.

Plastic SCM : 유니티 내 협업과 버전 컨트롤에 특화된 SCM.
https://www.plasticscm.com/


모든 프로젝트에 대해 동일한 폴더 구조 적용


폴더 구조를 결정했다면 앞으로 진행할 프로젝트에도 템플릿을 재사용할 수 있도록 위와 같이 에디터 스크립트를 구성할 수 있습니다.

Editor 폴더에 이 스크립트가 배치함으로써 "PROJECT_NAME" 변수와 매칭되는 에셋에 루트 폴더를 생성할 수 있고, 이를 통해 서드파티 패키지로부터 작업을 분리할 수 있습니다.

이 섹션을 완벽하게 이해하기 위해서는 유니티 에디터 스크립트와 특수 폴더 등에 대한 이해가 필요합니다.


빈 폴더

빈 폴더는 버전 컨트롤 과정에서 문제를 발생시킬 가능성이 있으므로 실제로 필요한 폴더만 만들어야 합니다. Git과 Perforce는 기본적으로 빈 폴더를 무시하며, 폴더 내에 파일이 배치되지 않는 이상 commit에 영향을 끼치지 않습니다.

Note: git의 경우 ".gitkeep" 파일을 배치해 빈 폴더를 commit할 수 있습니다.

그러나 유니티는 프로젝트 내의 모든 파일과 폴더에 대해 .meta 파일을 생성합니다. 따라서 Git과 Perforce를 사용하면 빈 폴더에 대한 .meta 파일을 commit할 수 있지만, 폴더 자체에 대한 버전 컨트롤은 할 수 없습니다. 만약 다른 사람이 폴더를 변경하면, 유니티는 컴퓨터에 존재하지 않는 폴더에 대한 .meta 파일을 제거할 것입니다.

반면 Plastic SCM은 빈 폴더를 처리할 수 있습니다. Plastic SCM은 디렉터리를 엔티티로 간주하여 처리하며 버전 히스토리를 관리하기 때문에 이러한 문제를 방지합니다.


.meta 파일


.meta 파일은 프로젝트 내의 모든 파일과 폴더에 대해 자동 생성되며 해당 개체에 대한 정보를 저장합니다. 텍스쳐, 메쉬, 오디오 클립과 같은 import setting이 있는 에셋에 일반적이며, import setting이 변경되는 경우 이는 .meta 파일에 적용됩니다.
따라서 .meta 파일을 저장소에 commit하여 팀원들이 모두 같은 파일 설정으로 작업할 수 있도록 해야 합니다.


네이밍 컨벤션

프로젝트 폴더 구조와 더불어 모든 에셋들에 대해 일정한 네이밍 컨벤션을 설정하여 더욱 효율적인 팀 협업을 수행할 수 있습니다.

프로젝트 구조와 마찬가지로 이 역시 반드시 지켜야 한다고 정해진 부분은 없지만, 아래와 같은 요소들을 고려할 수 있습니다.

  • 줄임말을 사용하지 않고 구체적인 이름 사용
    당신의 줄임말은 남들이 이해하지 못하고 기억하기도 힘들 수 있습니다.
    줄임말과 철자 실수는 혼동을 일으키니 유의하세요.
GOODBAD
largeButton, LargeButtonlButton
  • camelCase와 PascalCase 사용
    이름에 공백을 넣지 마세요.
    camelCase와 PascalCase는 가독성을 높입니다.
GOODBAD
OutOfMemoryException, dateTimeFormatOutofmemoryexception, datetimeformat
  • 언더스코어_ 와 하이픈- 은 아껴서 사용
    일반적으로 언더스코어나 하이픈을 사용하는 것을 지양하세요.
    그렇지만 특정 상황에서는 유용하게 사용될 수 있습니다.
    언더스코어를 접두사로 사용하면 이름에 대해 빠른 알파벳 순서를 지정할 수 있습니다.
    또한 특정 객체로부터 파생을 표시하는 데도 사용할 수 있습니다.
Active StatesTexture MapsLevel of Detail
EnterButton_Active, EnterButton_InactiveFollage_Diffuse, Follage_NormalmapBuilding_LOD1, Building_LOD0
  • Sequence를 나타내기 위해 숫자 접미사 사용
    순서나 연속성을 나타내기 위해 숫자를 접미사로 사용할 수 있습니다.
    그렇지 않은 경우에는 숫자를 접미사로 사용하는 것은 지양하는 것이 좋습니다.
Nodes of a path
Node0, Node1, Node2, etc.
  • 디자인 문서 그대로 사용
    디자인 문서가 있다면 임의로 변경하지 말고 정확한 철자 그대로 사용하세요.

에셋 분할

하나의 대규모 유니티 씬은 협업에 적합하지 않습니다.
아티스트, 디자이너와의 원활한 협업을 위해 conflict 위험을 최소화하며 씬을 작은 레벨의 씬들로 나누세요.

SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive)를 통해 런타임에도 추가적으로 씬을 로드할 수 있습니다.

또한 프리팹이 있는 씬을 수정하는 것이 아닌, 프리팹을 수정함을 통해 작업함으로써 다른 사람과의 conflict를 방지할 수 있습니다. 따라서 작업의 단위를 프리팹으로 나누고 네스티드 프리팹 기능을 활용하는 것이 좋습니다.

씬과 프리팹에 대해 타인의 작업물과 conflict가 발생한 경우, 유니티의 Smart merge 기능을 사용하여 이를 해결할 수 있습니다. 사람이 읽을 수 있는 YAML 언어 툴을 제공하여 conflict 처리와 merge를 지원합니다.

네스티드 프리팹 Nested Prefab
https://docs.unity3d.com/kr/2022.2/Manual/NestedPrefabs.html

스마트 병합 Smart Merge
https://docs.unity3d.com/kr/2022.2/Manual/SmartMerge.html


프리셋

프리셋을 통해 인스펙터 내의 거의 모든 것의 기본 상태를 설정할 수 있습니다. 선택한 컴포넌트나 에셋에 대해 설정한 프리셋을 복사하거나 자체적인 에셋으로 저장하고, 이를 다른 개체에 적용할 수 있습니다.

팀의 협업에 일관된 프리셋을 지정하여 표준을 설정하거나 새로운 에셋에 대해 적합한 설정을 적용하세요.

다음은 프리셋을 활용하는 방법의 예시입니다.

  • 기본값이 있는 GameObject 생성
    프리셋 에셋을 Hierarchy에 drag&drop하여 해당 프리셋이 적용된 컴포넌트를 지닌 GameObject를 생성할 수 있습니다.

  • 특정 타입을 프리셋과 연동
    Project Settings > Preset Manager에서 타입에 대한 프리셋을 설정함을 통해 해당 타입의 컴포넌트가 생성될 때 프리셋이 기본값으로 적용됩니다.

  • 세이브/로드 관리자 설정
    Manager Window에 대한 프리셋을 설정할 수도 있습니다. 동일한 tag 설정이나 물리 설정 등을 사용하는 다른 프로젝트의 사전 설정에 소요되는 시간을 줄일 수 있습니다.


코딩 컨벤션

코딩 컨벤션은 네이밍 컨벤션과 마찬가지로 정해진 것은 없지만, 최적의 방식을 선택한 다음에는 팀원 전체가 이를 일관성 있게 유지할 수 있도록 해야 합니다.

namespace를 사용하여 코드를 더욱 정확히 구성할 수 있습니다.
프로젝트 내의 모듈을 분리함으로써 서드파티 에셋과 혹시나 겹칠 수 있는 클래스명의 conflict를 피할 수 있습니다.

Note: 코드 내에서 namespace를 사용하는 경우 폴더 구조를 namespace에 따라 분할하여 더욱 나은 구성을 할 수 있습니다.

코드 템플릿에 표준 헤더(standard header)를 포함하여 클래스의 목적, 시간, 제작자 등을 문서화할 수도 있습니다. 시간이 지날수록 버전 컨트롤을 사용하더라도 손실될 수 있는 정보들을 손쉽게 관리할 수 있게 합니다.

Unity Editor의 Resources/ScriptTemplates에 위치한 스크립트 템플릿 파일들을 수정하여 Monobehavior 뿐만 아니라 셰이더나 behavior 스크립트, 어셈블리 정의 등에 대한 스크립트 템플릿을 설정할 수 있습니다. 단, 백업에 주의해야하며 새로운 버전의 유니티로 업데이트할 때마다 스크립트 템플릿이 해당 버전의 기본값으로 재설정되니 다시 템플릿을 수정하는 작업이 요구됩니다.

특정 프로젝트에서 스크립트 템플릿을 설정하기 위해서는 Assets/ScriptTemplates 폴더를 생성하고 여기에 스크립트 템플릿을 복사하여 원하는 설정을 재정의할 수 있습니다.


Reference

profile
Hi there :D

0개의 댓글