Version: 2020.3
언어: 한국어
패키지 매니페스트 창
패키지 에셋에 액세스

패키지용 스크립팅 API

패키지 관리자 스크립팅 API를 사용하면 C# 스크립트로 패키지 관리자와 상호작용할 수 있습니다. 예를 들어, 타겟 컴퓨터의 플랫폼에 따라 특정 패키지나 버전을 설치해야 할 수 있습니다.

이 시스템은 PackageManager.Client 클래스에 크게 의존합니다. 이 클래스를 이용하면 스크립팅을 통해 패키지를 찾고, 패키지 리스트를 탐색하고, 패키지를 설치하거나 제거할 수 있습니다.

또 다른 주요 클래스로는 PackageManager.PackageInfo가 있습니다. 이 클래스에는 패키지 매니페스트와 레지스트리에서 획득한 메타데이터 등과 같은 패키지 상태가 들어 있습니다. 예를 들어 패키지에 이용 가능한 버전 리스트 또는 패키지를 찾거나 설치할 때 발생하는 오류 리스트를 가져올 수 있습니다.

프로젝트에 패키지 추가

이 예제에서는 Client 클래스를 사용하여 프로젝트에 패키지를 설치하거나 추가하는 방법을 설명합니다.

Client.Add를 사용하여 패키지를 추가할 수 있습니다. Client.Add 메서드를 호출하면 패키지 이름만 지정하거나, 특정 버전이 포함된 이름을 지정할 수 있습니다. 예를 들어 Client.Add("com.unity.textmeshpro")를 사용하면 TextMesh Pro 패키지의 최신 버전을 설치하거나, 최선 버전으로 업데이트합니다. Client.Add("com.unity.textmeshpro@1.3.0")를 사용하면 TextMesh Pro 패키지의 1.3.0 버전을 설치합니다.

Client.Add 메서드는 AddRequest 인스턴스를 반환합니다. 이 인스턴스를 사용하면 상태, 오류, 또는 패키지에 새로 추가된 PackageInfo 정보가 들어 있는 요청 리스폰스를 가져올 수 있습니다.

using System;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example {
   static class AddPackageExample
   {
       static AddRequest Request;
      
       [MenuItem("Window/Add Package Example")]
       static void Add()
       {
           // Add a package to the project
           Request = Client.Add("com.unity.textmeshpro");
           EditorApplication.update += Progress;
       }

       static void Progress()
       {
           if (Request.IsCompleted)
           {
               if (Request.Status == StatusCode.Success)
                   Debug.Log("Installed: " + Request.Result.packageId);
               else if (Request.Status >= StatusCode.Failure)
                   Debug.Log(Request.Error.message);

               EditorApplication.update -= Progress;
           }
       }
   }
}

프로젝트에서 패키지 리스트 탐색

이 예제에서는 Client 클래스를 사용하여 프로젝트에서 패키지에 대해 반복 작업을 수행하는 방법을 설명합니다.

Client.List 메서드는 ListRequest 인스턴스를 반환합니다. 이 인스턴스를 사용하면 List 작업 상태, 오류, 또는 반복할 수 있는 PackageCollection이 들어 있는 요청 리스폰스를 가져올 수 있습니다.

using System;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example {
   static class ListPackageExample
   {
       static ListRequest Request;
    
       [MenuItem("Window/List Package Example")]
       static void List()
       {
           Request = Client.List();    // List packages installed for the project
           EditorApplication.update += Progress;
       }

       static void Progress()
       {
           if (Request.IsCompleted)
           {
               if (Request.Status == StatusCode.Success)
                   foreach (var package in Request.Result)
                       Debug.Log("Package name: " + package.name);
               else if (Request.Status >= StatusCode.Failure)
                   Debug.Log(Request.Error.message);

               EditorApplication.update -= Progress;
           }
       }
   }
}

프로젝트에 패키지 포함

이 예제에서는 Client 클래스를 사용하여 프로젝트에 이미 설치된 패키지 중 하나를 포함하는 방법을 설명합니다. 메인 메서드는 Client.Embed 메서드입니다. 이 메서드는 패키지의 복사본을 생성한 후 프로젝트의 Packages 폴더에 저장합니다.

Client.Embed 메서드는 EmbedRequest 인스턴스를 반환합니다. 이 인스턴스를 사용하면 Embed 작업 상태, 오류, 또는 패키지에 새로 포함된 PackageInfo 정보가 들어 있는 요청 리스폰스를 가져올 수 있습니다.

또한 이 예제에서는 Client.List 메서드를 사용하여 프로젝트에 현재 설치된 패키지 컬렉션에 액세스한 후 포함되거나 내장되지 않은 첫 번째 패키지를 선택합니다.

Client.List 메서드는 ListRequest 인스턴스를 반환합니다. 이 인스턴스를 사용하면 List 작업 상태, 오류, 또는 반복할 수 있는 PackageCollection이 들어 있는 요청 리스폰스를 가져올 수 있습니다.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    static class EmbedPackageExample
    {
        static String targetPackage;
        static EmbedRequest Request;
        static ListRequest LRequest;

        [MenuItem("Window/Embed Package Example")]
        static void GetPackageName()
        {
            // First get the name of an installed package
            LRequest = Client.List();
            EditorApplication.update += LProgress;
        }

        static void LProgress()
        {
            if (LRequest.IsCompleted)
            {
                if (LRequest.Status == StatusCode.Success)
                {
                    foreach (var package in LRequest.Result)
                    {
                        // Only retrieve packages that are currently installed in the
                        // project (and are neither Built-In nor already Embedded)
                        if (package.isDirectDependency && package.source
                            != PackageSource.BuiltIn && package.source
                            != PackageSource.Embedded)
                        {
                            targetPackage = package.name;
                            break;
                        }
                    }

                }
                else
                    Debug.Log(LRequest.Error.message);

                EditorApplication.update -= LProgress;

                Embed(targetPackage);

            }
        }

        static void Embed(string inTarget)
        {
            // Embed a package in the project
            Debug.Log("Embed('" + inTarget + "') called");
            Request = Client.Embed(inTarget);
            EditorApplication.update += Progress;

        }

        static void Progress()
        {
            if (Request.IsCompleted)
            {
                if (Request.Status == StatusCode.Success)
                    Debug.Log("Embedded: " + Request.Result.packageId);
                else if (Request.Status >= StatusCode.Failure)
                    Debug.Log(Request.Error.message);

                EditorApplication.update -= Progress;
            }
        }
    }
}

패키지 관리자 이벤트

Events 클래스를 사용하면 패키지 관리자로 이벤트 핸들러를 등록할 수 있습니다. Events 클래스에는 구독할 수 있는 두 가지 이벤트가 포함되어 있으며, 패키지 관리자는 다음 지점에서 이 이벤트를 발생시킵니다.

  • 패키지 관리자가 종속성 리스트를 변경하기 직전(registeringPackages)
  • 패키지 관리자가 변경된 패키지 종속성 리스트를 임포트하여 컴파일한 후(registeredPackages)

다음 예는 이러한 두 이벤트를 모두 사용하는 방법을 보여줍니다.

registrationingPackages 이벤트의 사용 예시

using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    public class EventSubscribingExample_RegisteringPackages
    {
        public EventSubscribingExample_RegisteringPackages()
        {
            // Subscribe to the event using the addition assignment operator (+=).
            // This executes the code in the handler whenever the event is fired.
            Events.registeringPackages += RegisteringPackagesEventHandler;
        }

        // The method is expected to receive a PackageRegistrationEventArgs event argument.
        void RegisteringPackagesEventHandler(PackageRegistrationEventArgs packageRegistrationEventArgs)
        {
            Debug.Log("The list of registered packages is about to change!");

           foreach (var addedPackage in packageRegistrationEventArgs.added)
            {
                Debug.Log($"Adding {addedPackage.displayName}");
            }

            foreach (var removedPackage in packageRegistrationEventArgs.removed)
            {
                Debug.Log($"Removing {removedPackage.displayName}");
            }

            // The changedFrom and changedTo collections contain the packages that are about to be updated.
            // Both collections are guaranteed to be the same size with indices matching the same package name.
            for (int i = 0; i <= packageRegistrationEventArgs.changedFrom.Count; i++)
            {
                var oldPackage = packageRegistrationEventArgs.changedFrom[i];
                var newPackage = packageRegistrationEventArgs.changedTo[i];

                Debug.Log($"Changing ${oldPackage.displayName} version from ${oldPackage.version} to ${newPackage.version}");
            }
        }
    }
}

registeredPackages 이벤트의 사용 예시

using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    public class EventSubscribingExample_RegisteredPackages
    {
        // You must use '[InitializeOnLoadMethod]' or '[InitializeOnLoad]' to subscribe to this event.
        [InitializeOnLoadMethod]
        static void SubscribeToEvent()
        {
            // This causes the method to be invoked after the Editor registers the new list of packages.
            Events.registeredPackages += RegisteredPackagesEventHandler;
        }

        static void RegisteredPackagesEventHandler(PackageRegistrationEventArgs packageRegistrationEventArgs)
        {
            // Code executed here can safely assume that the Editor has finished compiling the new list of packages
            Debug.Log("The list of registered packages has changed!");
        }
    }
}
패키지 매니페스트 창
패키지 에셋에 액세스