이러한 모범 사례는 기술 및 비기술 구성원이 모두 포함된 팀이 버전 관리 시스템을 설정하고 원활한 협업을 계획하는 방법에 대해 현명한 결정을 내릴 수 있도록 돕기 위해 만든 무료 전자책, 게임 개발자를 위한 버전 관리 및 프로젝트 조직 모범 사례에서 확인할 수 있습니다.
Unity 프로젝트를 구성하는 단일한 방법은 없지만, 몇 가지 주요 권장 사항은 다음과 같습니다:
- 이름 지정 규칙과 폴더 구조를 문서화하세요. 스타일 가이드 및/또는 프로젝트 템플릿을 사용하면 파일을 더 쉽게 찾고 정리할 수 있습니다. 팀에 적합한 것을 선택하고 모든 사람이 이에 동참할 수 있도록 하세요.
- 이름 지정 규칙에 일관성을 유지하세요. 선택한 스타일 가이드나 템플릿에서 벗어나지 마세요. 이름 지정 규칙을 수정해야 하는 경우 영향을 받는 에셋을 한 번에 파싱하고 이름을 변경하세요. 변경 사항이 많은 수의 파일에 영향을 미치는 경우 스크립트를 사용하여 업데이트를 자동화하는 것이 좋습니다.
- 파일 및 폴더 이름에 공백을 사용하지 마세요. Unity의 명령줄 툴에는 공백이 포함된 경로 이름과 관련된 문제가 있습니다. 공백을 대체할 수 있는 카멜케이스를 사용하세요.
- 테스트 또는 샌드박스 영역을 분리하세요. 비프로덕션 장면과 실험을 위한 별도의 폴더를 만드세요. 사용자 이름이 있는 하위 폴더는 팀원별로 작업 영역을 나눌 수 있습니다.
- 루트 수준에서 여분의 폴더를 만들지 마세요. 일반적으로 콘텐츠 파일은 Assets 폴더에 저장합니다. 꼭 필요한 경우가 아니라면 프로젝트의 루트 레벨에 추가 폴더를 만들지 마세요.
- 내부 자산을 타사 자산과 분리하여 보관하세요. 에셋 스토어 또는 다른 플러그인의 에셋을 사용하는 경우 자체 프로젝트 구조가 있을 가능성이 높습니다. 자신의 자산은 따로 보관하세요.
참고: 프로젝트에 타사 에셋이나 플러그인을 수정하는 경우 버전 관리를 통해 플러그인에 대한 최신 업데이트를 받을 수 있습니다. 업데이트를 가져온 후에는 차이점을 살펴보고 수정 사항을 덮어쓴 부분을 확인하고 다시 구현할 수 있습니다.
정해진 폴더 구조는 없지만, 다음 두 섹션에서는 Unity 프로젝트를 설정하는 방법에 대한 예시를 보여줍니다. 이 두 가지 구조는 모두 에셋 유형별로 프로젝트를 분할하는 것을 기반으로 합니다.
에셋 유형 매뉴얼 페이지에서 가장 일반적인 에셋에 대해 자세히 설명합니다. 폴더 구조를 정리할 때 템플릿 또는 Learn 프로젝트를 사용하여 더 많은 영감을 얻을 수 있습니다. 이러한 폴더 이름에 국한되지는 않지만 좋은 출발점이 될 수 있습니다.
Unity 허브에서 템플릿 또는 스타터 프로젝트 중 하나를 다운로드하면 에셋 유형별로 하위 폴더가 분할되어 있는 것을 확인할 수 있습니다. 선택한 템플릿에 따라 여러 공통 에셋을 나타내는 하위 폴더가 표시됩니다.
처음부터 강력한 프로젝트 구조를 정의하면 나중에 버전 관리 문제를 방지하는 데 도움이 됩니다. 한 폴더에서 다른 폴더로 자산을 이동하는 경우, 많은 VCS는 이를 이동하는 파일이 아니라 하나의 파일을 삭제하고 다른 파일을 추가하는 것으로 인식합니다. 이렇게 하면 원본 파일의 기록이 손실됩니다.
Plastic SCM은 Unity 내에서 파일 이동을 처리하고 이동한 모든 파일의 기록을 보존할 수 있습니다. 하지만 에셋 파일과 함께 .meta 파일이 이동하도록 편집기에서 파일을 이동하는 것이 중요합니다.
프로젝트의 폴더 구조를 결정한 후에는 에디터 스크립트를 사용하여 템플릿을 재사용하고 앞으로 진행할 모든 프로젝트에 동일한 폴더 구조를 만드세요. 에디터 폴더에 배치하면 아래 스크립트가 "PROJECT_NAME" 변수와 일치하는 에셋에 루트 폴더를 생성합니다. 이렇게 하면 자체 작업과 타사 패키지를 분리할 수 있습니다.
빈 폴더는 버전 관리에 문제를 일으킬 수 있으므로 꼭 필요한 폴더만 만들도록 하세요. Git 및 Perforce를 사용하면 기본적으로 빈 폴더는 무시됩니다. 이러한 프로젝트 폴더가 설정되어 있고 누군가 커밋을 시도하면 폴더에 무언가를 넣을 때까지 실제로는 작동하지 않습니다.
참고: 일반적인 해결 방법은 빈 폴더 안에 '.keep' 파일을 넣는 것입니다. 이 정도면 폴더를 리포지토리에 커밋할 수 있습니다.
플라스틱 SCM은 빈 폴더를 처리할 수 있습니다. 디렉토리는 Plastic SCM에서 각각 고유한 버전 기록이 첨부된 엔티티로 취급됩니다.
Unity에서 작업할 때 명심해야 할 점입니다. Unity는 폴더를 포함하여 프로젝트의 모든 파일에 대해 .meta 파일을 생성합니다. Git 및 Perforce를 사용하면 사용자는 빈 폴더에 대한 .meta 파일을 쉽게 커밋할 수 있지만 폴더 자체는 버전 관리 대상에 포함되지 않습니다. 다른 사용자가 최신 변경 사항을 받으면 해당 사용자의 머신에 존재하지 않는 폴더에 대한 .meta 파일이 생성되며, Unity는 해당 .meta 파일을 삭제합니다. Plastic SCM은 버전 제어에 빈 폴더를 포함시켜 이 문제를 완전히 방지합니다.
Unity는 프로젝트 내의 다른 모든 파일에 대해 .meta 파일을 생성하며, 일반적으로 자동 생성된 파일을 버전 관리에 포함시키는 것은 바람직하지 않지만 .meta 파일은 조금 다릅니다. 버전 관리 창에서 메타 파일 표시 모드가 켜져 있어야 합니다(기본 제공 Plastic SCM 또는 Perforce 모드를 사용하지 않는 경우).
.meta 파일은 자동으로 생성되지만 연결된 파일에 대한 많은 정보를 담고 있습니다. 이는 텍스처, 메시, 오디오 클립 등과 같이 가져오기 설정이 있는 에셋에 일반적으로 적용됩니다. 해당 파일에서 가져오기 설정을 변경하면 변경 사항이 에셋 파일이 아닌 .meta 파일에 기록됩니다. 그렇기 때문에 모든 사람이 동일한 파일 설정으로 작업할 수 있도록 .meta 파일을 리포지토리에 커밋합니다.
표준에 대한 합의는 프로젝트 폴더 구조에서 끝나지 않습니다. 모든 게임 에셋에 특정 명명 표준을 설정하면 팀이 서로의 파일에서 작업할 때 더 쉽게 작업할 수 있습니다.
게임 오브젝트에 대한 명확한 명명 표준은 없지만, 위의 표를 참고하세요.
단일의 대규모 Unity 씬은 협업에 적합하지 않습니다. 레벨을 여러 개의 작은 씬으로 나누어 아티스트와 디자이너가 하나의 레벨에서 원활하게 협업하면서 충돌 위험을 최소화할 수 있습니다.
런타임에 프로젝트는 LoadSceneMode.Additive 파라미터 모드를 전달하는 LoadSceneAsync와 함께 SceneManager를 사용하여 씬을 추가적으로 로드할 수 있습니다.
가능하면 작업을 프리팹으로 나누고 중첩된 프리팹의 기능을 활용하는 것이 가장 좋습니다. 나중에 변경해야 하는 경우 씬에서 작업 중인 다른 사용자와 충돌을 피하기 위해 프리팹이 있는 씬이 아닌 프리팹을 변경할 수 있습니다. 버전 관리에서 Diff를 수행할 때 프리팹 변경 사항을 더 쉽게 읽을 수 있는 경우가 많습니다.
씬 충돌이 발생하는 경우 Unity에는 씬과 프리팹을 병합하는 데 사용되는 YAML(사람이 읽을 수 있는 데이터 직렬화 언어) 툴도 내장되어 있습니다. 자세한 내용은 Unity 문서에서 스마트 병합을 참조하세요.
사전 설정을 사용하면 인스펙터에서 거의 모든 항목의 기본 상태를 사용자 지정할 수 있습니다. 프리셋을 만들면 선택한 컴포넌트나 에셋의 설정을 복사하여 자체 에셋으로 저장한 다음 나중에 다른 항목에 동일한 설정을 적용할 수 있습니다.
프리셋을 사용하여 표준을 적용하거나 새 자산에 합리적인 기본값을 적용하세요. 팀 전체에 일관된 표준을 적용하여 흔히 간과하는 설정이 프로젝트 성과에 영향을 미치지 않도록 할 수 있습니다.
컴포넌트의 오른쪽 상단에 있는 프리셋 아이콘을 클릭합니다. 프리셋을 자산으로 저장하려면 현재를 다음에 저장...을 클릭한 다음 사용 가능한 프리셋 중 하나를 선택하여 값 집합을 로드합니다.
다음은 프리셋을 사용하는 다른 편리한 방법입니다:
- 기본값을 사용하여 게임 오브젝트를 만듭니다: 프리셋 에셋을 계층구조로 끌어다 놓아 프리셋 값을 포함하는 해당 컴포넌트가 있는 새 게임 오브젝트를 생성합니다.
- 특정 유형을 프리셋과 연결합니다: 프리셋 관리자(프로젝트 설정 > 프리셋 관리자)에서 유형별로 하나 이상의 프리셋을 지정합니다. 그러면 새 컴포넌트를 만들면 지정된 프리셋 값이 기본값으로 적용됩니다.
- 전문가 팁: 유형별로 여러 개의 프리셋을 만들고 필터를 사용하여 이름별로 올바른 프리셋을 연결할 수 있습니다.
- 관리자 설정을 저장하고 로드합니다: 관리자 창에 사전 설정을 사용하여 설정을 재사용할 수 있습니다. 예를 들어 동일한 태그와 레이어 또는 물리 설정을 다시 적용하려는 경우 프리셋을 사용하면 다음 프로젝트의 설정 시간을 줄일 수 있습니다.
마찬가지로 코딩 표준은 팀의 작업 일관성을 유지하여 개발자가 프로젝트의 다른 영역 간에 쉽게 전환할 수 있도록 해줍니다. 다시 말하지만, 여기에는 정해진 규칙이 없습니다. 팀에 가장 적합한 것이 무엇인지 결정해야 하지만, 일단 결정한 후에는 그 결정을 고수해야 합니다.
예를 들어 네임스페이스는 코드를 보다 정확하게 정리할 수 있습니다. 이를 통해 프로젝트 내에서 모듈을 분리하고 클래스 이름이 반복될 수 있는 타사 에셋과의 충돌을 방지할 수 있습니다.
참고: 코드에서 네임스페이스를 사용할 때는 폴더 구조를 네임스페이스별로 나누면 더 잘 정리할 수 있습니다.
표준 헤더를 사용하는 것도 좋습니다. 코드 템플릿에 표준 헤더를 포함하면 클래스의 목적, 만든 날짜, 만든 사람까지 문서화할 수 있어 버전 관리를 사용하더라도 프로젝트의 긴 역사에서 쉽게 놓칠 수 있는 모든 정보를 기록할 수 있습니다.
Unity는 프로젝트에서 새로운 모노비헤이비어를 생성할 때마다 스크립트 템플릿을 사용합니다. 새 스크립트나 셰이더를 생성할 때마다 Unity는 %EDITOR_PATH%\Data\Resources\ScriptTemplates에 저장된 템플릿을 사용합니다:
- Windows C:\Program Files\Unity\Editor\Data\Resources\ScriptTemplates
- Mac: /애플리케이션/허브/에디터/[버전]/유니티/유니티.앱/콘텐츠/리소스/스크립트템플릿
기본 모노비헤이비어 템플릿은 이 템플릿입니다: 81-C# Script-NewBehaviourScript.cs.txt
셰이더, 기타 동작 스크립트 및 어셈블리 정의에 대한 템플릿도 있습니다.
프로젝트별 스크립트 템플릿의 경우 자산/스크립트 템플릿 폴더를 만들고 스크립트 템플릿을 이 폴더에 복사하여 기본값을 재정의합니다.
모든 프로젝트에 대해 기본 스크립트 템플릿을 직접 수정할 수도 있지만, 변경하기 전에 원본을 백업해야 합니다. Unity의 각 버전에는 고유한 템플릿 폴더가 있으므로 새 버전으로 업데이트할 때 템플릿을 다시 교체해야 합니다. 아래 코드 예제는 원본 81-C# Script-NewBehaviourScript.cs.txt 파일의 모양을 보여줍니다.
아래 예시에는 도움이 될 수 있는 두 가지 키워드가 있습니다:
- #스크립트 이름#은 입력한 파일 이름 또는 기본 파일 이름(예: NewBehaviourScript)을 나타냅니다.
- #NOTRIM#은 괄호 안에 한 줄의 공백을 포함하도록 합니다.
고유한 키워드를 사용하고 에디터 스크립트로 대체하여 OnWillCreateAsset 메서드를 구현할 수 있습니다.
스크립트 템플릿 내에서 다음 스크립트 예제의 헤더를 사용합니다. 이렇게 하면 모든 새 스크립트에 날짜, 스크립트를 만든 사용자, 원래 소속된 프로젝트가 표시된 헤더가 생성됩니다. 이는 향후 프로젝트에서 코드를 재사용할 때 유용합니다.