특수 폴더와 스크립트 컴파일 순서
어셈블리 정의 프로퍼티

어셈블리 정의

프로젝트의 스크립트를 어셈블리에 정리하기 위해 어셈블리 정의를 만들 수 있습니다. 폴더에 어셈블리 정의 에셋을 만들면 Unity는 폴더의 모든 스크립트를 이용하여 별도의 관리되는 어셈블리를 컴파일합니다. 이때 하위 폴더의 스크립트는 자체적인 어셈블리 정의가 없는 경우 함께 포함됩니다. 이러한 관리되는 어셈블리는 Unity 프로젝트 내에서 개별 라이브러리 역할을 합니다.

어셈블리 정의 에셋은 파일 확장자가 .asmdef인 텍스트 파일로, Assembly Definition 프로퍼티를 정의하는 JSON 스트링을 포함합니다. 에셋 파일을 선택하여 Unity 인스펙터 창에서 해당 프로퍼티를 설정하십시오. 외부 에디터를 사용하면 JSON을 직접 편집할 수도 있습니다. JSON 구문에 대한 자세한 내용은 어셈블리 정의 파일 포맷을 참조하십시오.

어셈블리 정의 이점

코드를 잘 정의된 종속 관계가 있는 어셈블리로 분리하면 Unity는 스크립트 변경 시 종속된 어셈블리만 재빌드하여 컴파일 시간을 단축합니다. 어셈블리 정의는 플랫폼과 Unity 버전별 코드가 포함된 프로젝트의 종속성을 관리하는 데에도 유용합니다.

어셈블리 정의가 없으면 Unity는 프로젝트의 모든 C# 스크립트를 사전 정의된 관리되는 어셈블리 중 하나에 컴파일합니다. 스크립트를 변경하면 Unity는 프로젝트 전체의 모든 스크립트를 다시 컴파일해야 합니다. 즉, 프로젝트에 스크립트를 추가할수록 코드를 변경한 후 변경 내용이 실행될 때까지 소요되는 시간이 증가합니다.

참고: 필수 사항은 아니지만, 프로젝트에서 어셈블리 정의를 사용할 때마다 프로젝트의 모든 코드에 대해 사용하는 것이 좋습니다. 그렇지 않으면 사전 정의된 어셈블리 하나의 스크립트를 변경할 때마다 Unity가 프로젝트의 모든 코드를 다시 컴파일해야 합니다. 이는 사전 정의된 어셈블리가 어셈블리 정의를 사용하여 생성한 어셈블리에 자동으로 종속되기 때문입니다.

다음 그림은 여러 개의 어셈블리로 분할된 프로젝트를 나타냅니다.

사전 정의된 어셈블리 vs 수동으로 정의된 어셈블리
사전 정의된 어셈블리 vs 수동으로 정의된 어셈블리

Unity는 기본적으로 거의 모든 프로젝트 스크립트를 Assembly-CSharp.dll 관리되는 어셈블리로 컴파일합니다. 예시는 대신 5개의 어셈블리로 나뉜 프로젝트를 나타냅니다. Main.dll 어셈블리는 Stuff.dllThirdParty.dll에 종속되며, Stuff.dllLibrary.dll에 종속됩니다. 결과적으로 Unity는 Main.dll의 코드 변화로 인해 다른 어셈블리를 재컴파일할 필요가 없습니다. 또한 Main.dll은 포함된 스크립트 수가 더 적으므로 Asmbly-CSharp.dll보다 빠르게 컴파일됩니다. 마찬가지로 Stuff.dll의 코드가 변경되면 Unity는 Main.dllStuff.dll만 재컴파일하면 되며, ThirdParty.dll이나 Library.dll은 재컴파일할 필요가 없습니다.

참고: Unity가 특정 C# 파일을 어디에 컴파일하는지 확인하려면 프로젝트 창에서 스크립트 파일을 선택하고 인스펙터의 Assembly Information 목록을 살펴보십시오.

Assembly-CSharp-Editor.dll 사전 정의된 어셈블리의 스크립트
Assembly-CSharp-Editor.dll 사전 정의된 어셈블리의 스크립트

어셈블리 정의 레퍼런스 에셋

어셈블리 정의 레퍼런스 에셋을 사용하여 기존 어셈블리 정의 에셋에 폴더를 추가할 수 있습니다.

어셈블리 정의 사용

Unity 프로젝트의 폴더에 어셈블리 정의 에셋을 추가하여 어셈블리를 정의합니다. 컴파일 후 어셈블리는 폴더와 하위 폴더(하위 폴더에 자체적인 어셈블리 정의가 있는 경우 제외)의 모든 스크립트를 포함합니다. 인스펙터에서 어셈블리의 이름을 설정합니다.

어셈블리 정의는 Unity 에셋의 한 가지 타입입니다. 프로젝트 창에서 기존의 어셈블리 정의를 선택하여 프로퍼티를 보거나 변경할 수 있습니다. 어셈블리 정의 에셋 파일 포맷에 관한 내용은 파일 포맷을 참조하십시오.

어셈블리 정의 에셋을 만들려면 다음 단계를 따르십시오.

  1. 프로젝트 창에서 어셈블리 정의를 추가할 폴더를 선택합니다.
  2. Assets > Create > Assembly Definition 에서 새 어셈블리 정의를 생성합니다.
  3. 새로 생성한 어셈블리 정의를 선택합니다.
  4. 인스펙터 창에서 해당 프로퍼티를 설정합니다.

어셈블리 정의 레퍼런스 에셋을 만들려면 다음 단계를 따르십시오.

  1. 프로젝트 창에서 기존 어셈블리 정의 에셋에 추가할 폴더를 선택합니다.
  2. Assets > Create > Assembly Definition Reference 에서 어셈블리 정의 레퍼런스 에셋을 생성합니다.
  3. 새로 생성한 어셈블리 정의 레퍼런스를 선택합니다.
  4. 폴더를 추가할 어셈블리 정의 에셋을 참조하도록 Assembly Defintion 프로퍼티를 설정합니다.
어셈블리 정의 레퍼런스 에디터
어셈블리 정의 레퍼런스 에디터

폴더당 하나의 어셈블리 정의 또는 어셈블리 정의 레퍼런스만 생성할 수 있습니다.

이미 어셈블리 정의 또는 어셈블리 정의 레퍼런스가 있는 폴더의 하위 폴더에 어셈블리 정의 또는 어셈블리 정의 레퍼런스를 만들면 Unity는 하위 폴더에 있는 모든 스크립트와 그 자식을 부모 폴더에 정의된 어셈블리가 아닌 하위 폴더에 정의된 어셈블리로 컴파일합니다.

GUID 사용

Use GUID 옵션은 Unity가 어셈블리 정의 에셋에 대한 레퍼런스를 직렬화하는 방식을 제어합니다. Use GUID를 활성화하면 Unity는 레퍼런스를 어셈블리 정의 이름이 아니라 에셋의 GUID로 저장합니다. 이름 대신 GUID를 사용하는 것은 항상 바람직합니다. 이렇게 하면 참조하는 다른 어셈블리 정의 또는 어셈블리 정의 레퍼런스 파일을 업데이트하지 않고도 어셈블리 정의 에셋의 이름에 변경 사항을 적용할 수 있습니다.

버전 정의

버전 정의를 사용하면 현재 프로젝트에 포함된 다양한 리소스 및 패키지 간의 종속성을 효과적으로 처리할 수 있습니다. 패키지 관리자 패키지 또는 에셋 스토어 패키지를 통해 프로젝트를 공유할 때 유용합니다.

버전을 설정하려면 더하기 기호(+)를 선택하십시오. 원하는 만큼 많은 버전 정의를 어셈블리 정의에 추가할 수 있습니다. 정의를 삭제하려면 리스트에서 선택한 후 빼기 기호(-)를 클릭하십시오.

버전 정의를 추가하면 다음 프로퍼티가 나타납니다.

인스펙터의 버전 정의입니다. 이 예시에는 두 개의 활성 버전 정의가 있습니다.
인스펙터의 버전 정의입니다. 이 예시에는 두 개의 활성 버전 정의가 있습니다.
프로퍼티 설명
Resource 정의를 설정할 패키지나 모듈을 선택합니다. 이 리스트에는 프로젝트의 모든 활성 패키지와 모듈이 나와 있습니다.
Define 정의에 대한 이름을 설정합니다. 이 정의는 아래의 Expression 이 true를 반환할 때에만 설정됩니다.
Expression 선택한 모듈 또는 패키지의 시맨틱 버전 범위입니다. 수학적인 간격 표기법을 사용해야 합니다. 와일드카드는 지원되지 않습니다. 이 프로퍼티는 Microsoft의 .NET 패키지 관리자, NuGet과 동일한 버전 범위를 사용합니다.
Expression outcome 표현식이 나타내는 수학적 등식을 표시합니다.

이전 버전과의 호환성 및 암시적 종속 관계

사전 정의된 어셈블리는 Unity의 기존 사전 정의된 컴파일 시스템과의 호환성을 유지하기 위해 어셈블리 정의 에셋으로 생성한 모든 어셈블리를 참조합니다. 이는 사전 정의된 어셈블리가 활성 빌드 타겟과 호환되는 프로젝트의 모든 사전 컴파일된 어셈블리(예: 플러그인 또는 .dll)를 참조하는 방식과 유사합니다.

다음 다이어그램은 사전 정의된 어셈블리, 어셈블리 정의 에셋으로 생성된 어셈블리와 사전 컴파일된 어셈블리 간의 기본 종속 관계를 나타냅니다.

어셈블리 종속성
어셈블리 종속성

다이어그램의 숫자는 어셈블리 간 레퍼런스를 나타냅니다. 이는 다음과 같이 제어할 수 있습니다.

  1. 기본적으로 어셈블리 정의 에셋을 이용하여 생성하는 어셈블리는 사전 정의된 어셈블리에 의해 참조됩니다. 이 옵션은 인스펙터에서 Auto Referenced 옵션을 비활성화하여 어셈블리 정의 에셋에 대해 끌 수 있습니다. Assembly Definition 프로퍼티를 참조하십시오.
  2. 어셈블리 정의를 사용하여 생성된 어셈블리와 사전 정의된 어셈블리는 모두 사전 컴파일된 어셈블리(플러그인)를 자동으로 참조합니다. 이 기본 동작을 비활성화하려면 Plugin Inspector 에서 Auto Referenced 프로퍼티를 비활성화하십시오. 자세한 내용은 플러그인 인스펙터를 참조하십시오.
  3. 플러그인에 대해 Auto Referenced 를 해제하면 인스펙터에서 어셈블리 정의 에셋에 대해 명시적으로 레퍼런스를 설정할 수 있습니다. 에셋의 Override References 옵션을 활성화하고 플러그인에 대한 레퍼런스를 추가합니다. Assembly Definition 프로퍼티를 참조하십시오.

참고: 사전 컴파일된 어셈블리, 또는 어셈블리 정의 에셋으로 생성되는 어셈블리에 대해 Auto Referenced 옵션을 해제하면 사전 컴파일된 어셈블리의 클래스가 더 이상 해당 어셈블리의 클래스를 참조하거나 사용할 수 없습니다. 또한 사전 컴파일된 어셈블리를 위한 명시적 레퍼런스를 선언할 수 없습니다.

특수 폴더

Unity는 폴더 내에서 특정한 특수 이름이 지정된 스크립트를 다른 폴더의 스크립트와 다르게 취급합니다. 단, 이러한 폴더는 해당 폴더 내 또는 상위 폴더에 어셈블리 정의 에셋을 생성하면 더 이상 다르게 취급되지 않습니다. 이러한 변화는 Editor 폴더를 사용할 때 가장 잘 알아볼 수 있는데, 이러한 Editor 폴더는 보통 코드 정리 방식과 사용하는 에셋 패키지에 따라 프로젝트 전체에 걸쳐 분산되어 있습니다.

보통 Unity는 이름이 Editor인 폴더의 모든 스크립트를 이러한 스크립트의 위치와는 상관없이 사전 정의된 Assembly-CSharp-Editor 어셈블리에 컴파일합니다. 단, 하위 폴더 중 Editor 폴더가 있는 폴더에 어셈블리 정의 에셋을 생성하면 해당 에디터 스크립트가 사전 정의된 에디터 어셈블리가 아닌 어셈블리 정의에 의해 생성된 새로운 어셈블리로 전송됩니다. 이 위치는 잘못된 위치입니다. Editor 폴더를 관리하려면 다음 중 한가지 방법을 사용하십시오.

  • 해당하는 각 Editor 폴더에 어셈블리 정의 에셋을 추가하고 해당 어셈블리의 Platform 프로퍼티를 Editor Platform 에만 사용되도록 설정합니다.
  • 어셈블리 정의에 의해 처리되지 않는 중앙 위치로 모든 에디터별 코드를 이동합니다.

테스트 어셈블리

테스트 어셈블리는 프로젝트의 다른 코드를 테스트하는 코드를 포함합니다. 따라서 이러한 어셈블리는 프로젝트의 릴리스 빌드에 포함될 필요가 없으며, 테스트 어셈블리가 아닌 다른 어셈블리는 테스트 어셈블리에 종속되면 안 됩니다. Unity에서 테스트 어셈블리를 사용하고 싶다면 새로운 테스트 어셈블리를 만드는 방법에 대한 테스트 프레임워크 패키지 문서를 참조하십시오.

API

UnityEditor.Compilation 네임스페이스에서 CompilationPipeline 클래스를 사용하면 Unity가 프로젝트를 위해 빌드한 모든 어셈블리에 대한 정보를 검색해서 가져올 수 있습니다. 여기에는 어셈블리 정의 에셋에 기반하여 생성된 어셈블리도 포함됩니다.

예를 들어 다음 스크립트는 CompilationPipeline을 사용하여 프로젝트의 모든 현재 플레이어 어셈블리를 나열합니다.

using UnityEditor;
using UnityEditor.Compilation;

public static class AssemblyLister
{

    [MenuItem("Tools/List Player Assemblies in Console")]
    public static void PrintAssemblyNames()

    {
        UnityEngine.Debug.Log("== Player Assemblies ==");
        Assembly[] playerAssemblies = 
            CompilationPipeline.GetAssemblies(AssembliesType.Player);

        foreach (var assembly in playerAssemblies)
        {
            UnityEngine.Debug.Log(assembly.name);
        }
    }
}

어셈블리 정의 파일 포맷

어셈블리 정의 및 어셈블리 정의 레퍼런스 에셋은 JSON 파일입니다. 외부 툴을 이용하여 Unity 에디터 내의 에셋을 편집하거나 JSON 콘텐츠를 수정할 수 있습니다.

어셈블리 정의는 다음 필드가 포함된 JSON 객체입니다.

필드 타입
name 문자열
references (optional) 문자열 배열
includePlatforms (optional) 문자열 배열
excludePlatforms (optional) 문자열 배열
allowUnsafeCode(optional) bool
autoReferenced(optional) bool
overrideReferences(optional) bool
precompiledReferences(optional) 문자열 배열
defineConstraints(optional) 문자열 배열
optionalUnityReferences(optional) 문자열 배열

includePlatformsexcludePlatforms 필드는 같은 어셈블리 정의 파일에서 함께 사용될 수 없습니다.

어셈블리의 이름이나 에셋의 GUID를 사용하여 references 필드에 어셈블리 정의 에셋을 지정할 수 있습니다. 에셋 GUID를 사용하려면 값은 GUID:Asset GUID 와 같은 형태여야 합니다. 예를 들어 “GUID:0ec2b662ccc592241854c1b507df8a89” 를 사용할 수 있습니다. AssetDatabase.AssetPathToGUID는 에셋의 GUID를 검색해서 가져옵니다.

CompilationPipeline.GetAssemblyDefinitionPlatforms() 함수로 플랫폼 이름 스트링을 검색하여 가져올 수 있습니다(현재 에디터에 플랫폼 지원 설치 필요).

어셈블리 정의 레퍼런스는 다음 필드가 포함된 JSON 객체입니다.

필드 타입
reference 문자열

어셈블리의 이름이나 에셋의 GUID를 사용하여 참조된 어셈블리 정의 에셋을 지정할 수 있습니다. 에셋 GUID를 사용하려면 값은 GUID:Asset GUID와 같은 형태여야 합니다. 예를 들어 _“GUID:0ec2b662ccc592241854c1b507df8a89”를 사용할 수 있습니다. AssetDatabase.AssetPathToGUID는 에셋의 GUID를 검색해서 가져올 때 사용합니다.

예시 어셈블리 정의 JSON

MyLibrary.asmdef

{
    "name": "MyLibrary",
    "references": [ "Utility" ],
    "includePlatforms": ["Android", "iOS"]
}

MyLibrary2.asmdef

{
    "name": "MyLibrary2",
    "references": [ "GUID:0ec2b662ccc592241854c1b507df8a89" ],
     "excludePlatforms": ["WebGL"]
}
특수 폴더와 스크립트 컴파일 순서
어셈블리 정의 프로퍼티