Note: Follow the advice in this section in release order. For example, if you need to upgrade your project from 2019 to 2021, read the 2020 upgrade guide to see if there are any changes that you need to make before you read the 2021 upgrade guides.
이 페이지에는 2020에서 2021 LTS 버전으로 업그레이드할 경우 기존 프로젝트에 영향을 미칠 수 있는 Unity 2021 LTS 버전의 변경 사항이 나와 있습니다.
참고: 2021LTS는 2021.3으로도 알려져 있습니다.
This upgrade guide describes how to upgrade to version 2021 of Unity’s built-in render pipeline. To upgrade to other render pipelines to version 2021, see:
To upgrade other packages, refer to the documentation for the packages you are using.
이제 기기 시뮬레이터가 에디터에 포함되며, 게임 창에서 액세스할 수 있습니다.
기기 시뮬레이터를 설정하려면 UnityEngine.Device
네임스페이스를 다음의 Screen, Application 및 SystemInfo 클래스에 추가하십시오.
UnityEngine.Device.Screen;
UnityEngine.Device.Application;
UnityEngine.Device.SystemInfo;
UnityEngine.Device
로 전환하려면 시뮬레이터에서 사용하려는 각 스크립트에 다음 로직을 추가해야 합니다.
using Screen = UnityEngine.Device.Screen;
using Application = UnityEngine.Device.Application;
using SystemInfo = UnityEngine.Device.SystemInfo;
새로운 네임스페이스 UnityEngine.Device
가 시뮬레이터(에디터에 있는 경우)에서 런타임 빌드를 통해 실제 기기 API로 원활하게 전환됩니다.
이제 에디터가 기본 스카이박스 프로브 및 주변광 프로브를 자동으로 베이크하고, 씬을 수동으로 베이크하기 전까지 해당 데이터를 유지합니다. 업그레이드 시 주변광 기여가 없는 씬이 시각적으로 변경될 수 있습니다. 이러한 씬을 원래 모습으로 복원하려면 환경 조명 강도 멀티플라이어를 0으로 설정하십시오. 또는 스카이박스를 검은색으로 설정하고, 씬을 베이크한 후 스카이박스를 원하는 하늘 컬러로 초기화할 수도 있습니다.
이제 Unity의 프로그레시브 라이트매퍼가 기본적으로 모든 씬에 대해 주변광 프로브와 스카이박스 반사 프로브를 자동으로 생성합니다. 즉 씬이 Lighting 설정 패널의 Environment 탭에 지정된 설정에 따라 환경 조명을 자동으로 받습니다. 에디터는 조명이 생성되기 전까지 환경 조명이 변경될 때마다 주변광 프로브와 스카이박스 반사 프로브를 업데이트합니다. Generate Lighting 컨트롤을 사용하여 베이크하면 에디터는 프로브 업데이트를 중지하고, 다음 베이크에서만 프로브를 다시 업데이트합니다. Auto Generate 옵션을 활성화하면 에디터는 환경 조명이 변할 때마다 프로브를 계속 업데이트합니다. 조명을 생성하고 나서 프로젝트에서 조명 데이터 에셋을 제거하여 이 조명 데이터를 삭제하면, 에디터는 주변광 프로브와 스카이박스 반사 프로브를 자동으로 다시 생성합니다.
프로젝트를 업그레이드할 때 조치를 필요로 하는 한 가지 상황이 있습니다. 이러한 상황은 다음과 같은 프로젝트에서 환경 조명 기여를 원하지 않을 때입니다.
이 경우 Window > Rendering > Lighting Settings > Environment로 이동한 후 다음 변경 작업 중 하나를 수행하여 자동으로 생성된 주변광 프로브와 스카이박스 반사 프로브의 환경 기여를 비활성화하십시오.
코드 커버리지 관리를 위한 사용자 인터페이스가 일반 환경 설정에서 코드 커버리지 패키지 안으로 이동되었습니다.
코드 커버리지 패키지는 Unity 2019.3 이상용 패키지 관리자를 통해 릴리스된 패키지로 제공됩니다. 최신 버전은 1.0.0입니다.
다음 방법 중 하나를 사용하여 코드 커버리지를 활성화할 수 있습니다.
-enableCodeCoverage
를 사용합니다.Coverage.enabled
API를 사용합니다. 다음은 예제 클래스입니다.// Create a new C# script called CodeCoverageMenuItem and place it
// under the Editor folder.
// This class creates a toggle menu item under Code Coverage > Enable
// Code Coverage. Use it to enable/disable Code Coverage.
using UnityEditor;
using UnityEngine.TestTools;
class CodeCoverageMenuItem
{
const string EnableCodeCoverageItemName = "Code Coverage/Enable Code Coverage";
[MenuItem(EnableCodeCoverageItemName, false)]
static void EnableCodeCoverage()
{
Coverage.enabled = !Coverage.enabled;
}
[MenuItem(EnableCodeCoverageItemName, true)]
static bool EnableCodeCoverageValidate()
{
Menu.SetChecked(EnableCodeCoverageItemName, Coverage.enabled);
return true;
}
}
이전에는 일부 Force Field 프로퍼티가 프레임 속도에 따라 또는 Time Manager에서 Time Scale을 사용하는 경우 다르게 동작했습니다.
이제 파티클 시스템은 시뮬레이션의 기준으로 30fps의 레퍼런스 프레임 속도를 시뮬레이션의 기준으로 사용합니다. 앱이 다른 프레임 속도로 실행되는 경우 다음 설정이 이전 버전의 Unity와 다르게 작동할 수 있습니다.
이러한 설정이 영향을 받는 경우 영향을 받는 영역의 강도를 조정하여 원하는 형상을 얻으십시오.
이전에는 Rate over Distance 이미션이 Start Delay 설정을 무시했습니다. 이제는 Start Delay 설정이 정의되면 거리 기반 방출의 시작이 지연됩니다.
이 필드가 이전에 설정된 경우 조정해야 할 수 있습니다.
PackedAssets.file은 직접 교체 없이 사용되지 않는 것으로 표시되었습니다. 이전에는 BuildReport.files에 대한 파일 ID 또는 인덱스를 나타내는 정수를 포함했습니다. 이제 BuildReport 파일을 검색하려면 PackedAssets.shortPath를 사용해야 합니다.
실험 단계의 Terrain API가 비실험 단계의 네임스페이스로 이동되었습니다. Terrain API에 대한 다른 사소한 변경 사항도 있습니다. 실험 단계의 Terrain API를 사용한 경우 다음 API를 대신 사용하십시오.
UnityEngine.TerrainTools
;UnityEditor.TerrainTools
;UnityEngine.TerrainUtils
;다음은 API 변경 사항의 전체 리스트입니다.
UnityEngine.Experimental.TerrainAPI
및 UnityEditor.Experimental.TerrainAPI
는 이제 각각 UnityEngine.TerrainTools
및 UnityEditor.TerrainTools
입니다. 일부 런타임 API는 새로운 UnityEngine.TerrainUtils
네임스페이스로 이동했습니다.TerrainPaintTool<T>
클래스의 GetDesc()
가 GetDescription()
으로 이름이 변경되었습니다.TerrainUtility
클래스가 UnityEngine.Experimental.TerrainAPI
에서 UnityEngine.TerrainUtils
로 이동했습니다.TerrainUtility.TerrainMap
클래스는 더 이상 내부 클래스가 아니며, UnityEngine.TerrainUtils
네임스페이스에 속합니다.TerrainMap.TileCoord
구조는 더 이상 TerrainMap
클래스에 없고, TerrainTileCoord
로 이름이 변경되었으며, 이제 UnityEngine.TerrainUtils
네임스페이스의 일부입니다.UnityEditor.Experimental.TerrainAPI.BrushPreviewMode
열거형의 이름이 TerrainBrushPreviewMode
로 변경되고 UnityEditor.TerrainTools
네임스페이스로 이동했습니다.TerrainPaintUtilityEditor.BuiltinPaintMaterialPasses
열거형이 TerrainPaintUtilityEditor
클래스에서 UnityEditor.TerrainTools
네임스페이스로 이동했습니다. 또한 TerrainBuiltinPaintMaterialPasses
로 이름이 변경되었습니다.IOnInspectorGUI
의 세 가지 ShowBrushGUI
함수가 다른 과부하 함수 대신 기본 파라미터 값을 사용하는 단일 함수로 병합되었습니다.TerrainFilter
가 제거되었습니다. 대신에 System.Predicate<Terrain>
을 사용하십시오.Texture2D.Resize
및 해당 오버로드의 이름이 Texture2D.Reinitialize
로 변경되었습니다.
API 업데이터가 이 이름을 자동으로 변경해야 합니다. 그렇지 않은 경우 사용하는 Texture2D.Resize
를 Texture2D.Reinitialize
로 변경하십시오.
Android 빌드 파이프라인의 많은 부분이 증분 방식으로 변경되었으며, Unity는 이전 빌드 파이프라인에 있던 다음 기능을 제거했습니다.
libil2cpp.so
심볼을 생성합니다.The default launcherTemplate.gradle file has changed. If you use a custom launcher template, you must regenerate it and reapply your changes on top. Otherwise, your application can experience performance regressions if it uses Resources.Load.
기본 Image.scaleMode가 ScaleAndCrop에서 ScaleToFit으로 변경되었습니다.
The expected behavior for an image is to scale to the size of the element, so we changed the default value of Image.scaleMode to ScaleToFit. If you didn’t override the Image scale mode, some cropped images might shrink to fit the size of the element. If ScaleAndCrop was the expected mode for your images, you can override their style by adding the following value in your UXML file inline style:
-unity-background-scale-mode: scale-and-crop;
오버라이드를 통해 스타일 클래스를 만들고 ScaleAndCrop을 필요로 하는 이미지에 적용할 수도 있습니다.
기본 C# 런타임인 Mono가 최신 버전으로 업그레이드되었습니다. 여기에는 Mono 업스트림 버전의 많은 수정 사항과 몇 가지 주목할 만한 동작 변경 사항이 포함됩니다.
Directory.GetFiles
가 정렬된 리스트를 더 이상 반환하지 않습니다.
Directory.GetFiles(dir).OrderBy(f => f)
;Object.GetHashCode
는 다른 값을 반환하며, 운영체제 간의 결정론적 해싱 알고리즘으로 사용해서는 안 됩니다.
GetHashCode
의 결과를 현재 프로세스 외부에서 사용해서는 안 됩니다. 즉 직렬화하거나, 또는 다음 번에 코드가 새 프로세스에서 실행될 때 동일할 것으로 기대하지 마십시오. Unity는 MD5와 같은 결정론적 해싱 알고리즘을 사용할 것을 권장합니다.이제 Adaptive Performance 패키지 버전 3.0을 사용할 수 있습니다. 버전 3.0으로 업그레이드하는 방법은 어댑티브 퍼포먼스 업그레이드 가이드를 참조하십시오.
이전에는 RenderTexture.depth
프로퍼티를 32비트로 설정하면 플랫폼에 따라 D24_S8을 가져올 수 있었습니다. 이제는 32비트로 설정하면 현재 플랫폼에서 해당 포맷이 지원되는 경우 뎁스 컴포넌트에 대해 32비트인 D32_S8을 가져옵니다. 하지만 해당 뎁스 버퍼의 메모리 사용량이 두 배가 됩니다.
새로운 RenderTexture.depthStencilFormat
프로퍼티는 그래픽스 API가 비디오 메모리에 리소스를 생성하는 데 사용하는 포맷을 반환합니다. 이 프로퍼티를 사용하여 특정 포맷을 요청할 수도 있습니다. 하지만 일부 플랫폼은 모든 뎁스 스텐실 포맷을 지원하지 않습니다. DepthStencilFormat
프로퍼티를 지원되지 않는 포맷으로 설정하면 Unity는 뎁스 및 스텐실 컴포넌트에 대해 비트 수가 더 많거나 같은 호환 가능 포맷을 자동으로 선택합니다.
이제 RenderTexture 에셋이 선택된 뎁스 스텐실 포맷을 직렬화합니다. 포맷 대신 여러 개의 비트를 사용하는 API를 사용하는 경우 이러한 비트는 포맷에 매핑되고 해당 포맷이 직렬화됩니다. 뎁스가 16비트 이상으로 설정된 이전 버전의 RenderTexture 에셋은 D24_S8을 사용하도록 자동으로 업그레이드됩니다.
DirectX 그래픽스 API를 사용하는 일부 플랫폼(예: Windows)에서는 비트를 16보다 크게 설정하면 그래픽스 백엔드가 내부적으로 D32_S8 포맷을 선택하기 때문에 뎁스 비트 수가 더 적은 포맷을 사용하게 됩니다. 모든 플랫폼에서 일관된 업그레이드를 보장하기 위해 모든 플랫폼에서 D24_S8이 자동 업그레이더에 사용됩니다. 하지만 프로젝트에 RenderTexture 에셋이 있는 경우 프로젝트의 렌더 출력에 시각적 결함이 발생할 수 있습니다. 이러한 에셋을 검토하고, 필요한 경우 뎁스 스텐실 포맷을 D32_S8로 변경하십시오. 다음과 같은 문제가 발생할 수 있습니다.
다음 그래픽스 포맷은 지원이 중단되었습니다.
이러한 자동 포맷은 사용되는 정확한 포맷에 대해 명확하지 않으며, 플랫폼에 따라 다를 수 있습니다.
지원이 중단된 포맷의 사용을 제거하는 단계는 포맷 및 사용 사례에 따라 다릅니다.
현재 플랫폼의 자동 비디오 포맷을 가져오려면 SystemInfo.GetGraphicsFormat(DefaultFormat.Video)
를 사용하십시오.
GraphicsFormat API는 종종 DepthAuto 또는 ShadowAuto를 사용하여 컬러 버퍼 없는 뎁스 전용 렌더링을 통해 렌더 텍스처를 생성합니다. 다음은 이러한 사용 사례의 예입니다.
renderTextureDescriptor.graphicsFormat = GraphicsFormat.ShadowAuto
RenderTexture.GetTemporary(width, height, bits, GraphicsFormat.ShadowAuto)
뎁스 전용(컬러 없음) 렌더링을 표시하려면 GraphicsFormat.None을 새로운 컬러 포맷으로 사용하십시오.
renderTextureDescriptor.graphicsFormat = GraphicsFormat.None;
ShadowAuto를 사용한 경우 RenderTextureDescriptor의 shadowSamplingMode를 ShadowSamplingMode.CompareDepths로 설정하여 뎁스 텍스처에 대한 뎁스 비교 샘플링을 활성화하고, RenderTextureDescriptor를 사용하는 오버로드를 사용하도록 코드를 변경하십시오.
renderTextureDescriptor.shadowSamplingMode = ShadowSamplingMode.CompareDepths;
일부 상황에서 DepthAuto/ShadowAuto 포맷은 현재 플랫폼에 맞게 자동으로 선택된 뎁스 포맷을 나타냅니다. 이 경우 지원이 중단된 값을 바꾸려면 SystemInfo.GetGraphicsFormat(DefaultFormat.Depth/Shadow)
를 사용하십시오.
고급 사용자에게 제공되던 asm.js 링커 타겟은 더 이상 사용할 수 없습니다.
Pointer_stringify()
는 지원이 중단되었습니다. 대신에 UTF8ToString()
함수를 호출하여 UTF8로 인코딩된 null 종료 C 문자열을 WebAssembly 힙에서 JavaScript 문자열로 마샬링하십시오.프로그레시브 GPU 라이트매퍼는 CPU OpenCL 기기를 더 이상 지원하지 않습니다. 지원되는 GPU가 없지만 CPU OpenCL 기기가 감지된 경우 해당 기기를 건너뛰고 프로그레시브 CPU 라이트매퍼로 폴백한다는 경고 메시지가 나타납니다. 프로그레시브 CPU 라이트매퍼는 CPU 기반 라이트맵 계산을 위한 더 뛰어난 성능을 제공합니다. 이러한 동작 변경은 자동으로 이루어지며, 라이트맵은 예상대로 계산되어야 합니다.
Unity가 에셋 임포트 프로세스 중에 InitializeOnLoad
메서드를 호출하면 에셋 로드가 실패할 수 있습니다. 에셋 임포트 동안 에셋 데이터베이스는 업데이트 상태이며, Unity는 이미 임포트한 에셋을 확인할 수 없습니다. InitializeOnLoad
메서드는 임포트되지 않은 에셋을 로드할 수 없습니다.
에셋 임포트 프로세스를 개선하기 위해 OnPostprocessAllAssets
콜백이 향상되었습니다. 특히 OnPostprocessAllAssets
콜백은 다음을 수행할 수 있습니다.
didDomainReload
파라미터를 포함합니다.에셋 작업이 필요한 도메인 관련 초기화 로직을 OnPostprocessAllAsset
콜백으로 이동시킵니다. InitializeOnLoad
메서드 내에서 에셋 작업을 수행하지 마십시오.
다음 동작 변경 코드 예제는 에셋 작업이 이전에 어떻게 연기되었는지 보여줍니다.
예제1:
public class AssetPostprocessorTester1 : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
var assetPath = "Assets/hello.txt";
if (File.Exists(assetPath))
{
var txtObj = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/hello.txt");
AssetDatabase.DeleteAsset("Assets/hello.txt");
if (txtObj == null)
Debug.Log("New Behaviour: Asset object is unloaded");
else
Debug.Log("Old Behaviour: Asset is loaded for deleted asset!!");
}
}
}
예제2:
public class AssetPostprocessorTester2 : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
var assetPath = "Assets/SomeText.txt";
if (!File.Exists(assetPath))
{
File.WriteAllText(assetPath, "hello world");
AssetDatabase.ImportAsset(assetPath);
var txtObj = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath);
if (txtObj == null)
Debug.Log("Old Behaviour: Asset hasn't been imported yet");
else
Debug.Log("New Behaviour: Asset is imported and loaded");
}
}
}
다음 예제는 didDomainReload
파라미터가 있는 새로운 OnPostprocessAllAssets
배리언트를 보여줍니다.
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
{
if (didDomainReload)
Debug.Log("Domain has been reloaded");
else
Debug.Log("Domain did not reload during import");
}
이제 모든 도메인 재로드는 에셋 데이터베이스 내에서 처리됩니다.
OnPostprocessAllAssets
는 에셋 작업에서 더욱 잘 작동하지만, 이 콜백에서 처리하면 에셋 데이터베이스 새로고침 및 도메인 재로드 시간이 늘어납니다. InitializeOnLoad
메서드는 도메인 재로드 시간도 늘립니다. 반복 간에 에디터 응답성을 향상시키려면 이러한 콜백에서의 처리를 최소화하는 것이 좋습니다.
이제 혼합 모드 점 광원과 스폿 광원이 그림자 타입 설정에 관계없이 서브트랙티브 조명 모드를 사용하여 씬에서 베이크된 직접광을 일관되게 제공합니다. 따라서 영향을 받는 씬에서 정적 게임 오브젝트에 대한 스페큘러 조명이 누락된 것처럼 보일 수 있습니다. 이 문제를 해결하려면 영향을 받는 혼합 모드 광원을 실시간 모드 광원으로 교체하십시오. 베이크된 간접 또는 섀도우 마스크 조명 모드를 혼합 광원과 함께 사용할 수도 있습니다.
이제 셰이더 키워드 시스템은 셰이더당 또는 컴퓨트 셰이더당 최대 65534개의 로컬 키워드와 프로젝트당 232–2개의 전역 키워드를 허용합니다. 셰이더 또는 컴퓨트 셰이더에서 선언하는 모든 키워드는 이 셰이더에 속합니다. _local 접미사가 있는 지시문에서 선언하는 키워드는 전역 키워드 상태의 영향을 받지 않습니다.
예:
셰이더의 패스는 다음 키워드를 선언합니다.
#pragma shader_feature FOO BAR
#pragma shader_feature_local BOO BAZ
이 패스를 사용할 때 FOO 및 BAR 키워드는 전역적으로 또는 머티리얼에서 활성화된 경우에 활성화됩니다. BOO 및 BAZ 키워드는 머티리얼에서 활성화된 경우에만 활성화됩니다.
이제 Unity는 .NET Standard 2.1 API의 모든 API를 포함하여 .NET 기본 클래스 라이브러리에서 많은 추가 API를 지원합니다. 코드 중 하나라도 새 API와 충돌하는 경우 프로젝트가 컴파일되지 않을 수 있습니다.
이전 버전의 Unity에서 생성된 프로젝트를 업그레이드할 때 오류를 피하려면 코드를 확인한 후 업데이트하여 현재 .NET Standard 2.1에서 사용할 수 있는 타입 및 메서드와 충돌하도록 하십시오.
충돌의 원인은 다음과 같습니다.
코드가 .NET Standard 2.1에서 추가하는 타입 또는 메서드와 충돌하는 이름을 가진 타입이나 메서드를 구현하는 경우 코드가 컴파일되지 않습니다. 이름 충돌이 발생하면 모호한 레퍼런스로 인해 C# 컴파일러 오류가 발생할 수 있습니다.
예를 들어 프로젝트 코드에 MyCompany.MyCode.Range
라는 이름의 타입을 추가하면 기존 System.Range
타입과 충돌할 수 있습니다. using System;
및 using MyCompany;
문을 모두 포함하는 코드는 컴파일에 실패합니다.
오류를 방지하려면 충돌하는 이름의 타입에 대해 C# 코드에서 네임스페이스를 완전히 지정하십시오.
.NET Standard 2.1이 타입에 대해 직접 구현하는 확장 메서드가 기존 코드에 있는 경우 확장 메서드의 이름을 바꾸거나 기본 클래스 라이브러리에서 구현한 메서드를 사용하도록 선택할 수 있습니다.
예를 들어 프로젝트의 코드는 ArraySegment
타입에 CopyTo
라는 이름의 확장 메서드를 구현할 수 있습니다. .NET Standard 2.1에서 ArraySegment
에는 빌트인 CopyTo
메서드가 있습니다. CopyTo
확장 메서드의 이름을 바꾸거나, 완전히 제거하고 빌트인 메서드를 사용할 수 있습니다.
프로젝트가 이제 기본 클래스 라이브러리의 일부인 타입 및 메서드를 구현하는 사전 컴파일된 어셈블리(즉 관리되는 플러그인)를 사용하는 경우 프로젝트에서 이러한 어셈블리를 제거하고 빌트인 구현을 사용하십시오.
예를 들어 이전 버전의 Unity에서는 System.Span
값 타입에 액세스하려면 NuGet의 System.Memory.dll
어셈블리를 사용해야 했습니다. 이제 .NET Standard 2.1은 기본 클래스 라이브러리에서 System.Span
을 제공합니다. Unity 2021.2에서 관리 플러그인 System.Memory.dll
을 사용하려고 시도하면 프로젝트가 빌드에 실패합니다.
Microsoft는 Windows XR 플러그인에 대한 지원을 중단했으며, 이제 OpenXR 플러그인을 통해 WMR(Windows Mixed Reality) 기능 및 기기를 지원합니다.
Unity OpenXR 플러그인으로 업그레이드하려면 다음 단계를 따르십시오.
OpenXR 플러그인이 활성화되면 Microsoft에서 제공하는 Mixed Reality Feature Tool을 사용하여 필요한 지원 패키지를 설치할 수 있습니다.
WMR 기능, 툴 및 샘플을 설치하거나 업데이트하려면 다음 단계를 따르십시오.
Windows Mixed Reality를 사용하도록 신규 및 업데이트된 Unity 프로젝트를 설정하는 방법에 대한 자세한 내용은 Microsoft 문서 사이트에서 XR 구성 설정을 참조하십시오.