Version: 2017.4
Unity 5.0의 기타 업그레이드 참고 사항
Unity 3.5로 업그레이드

Unity 4.0으로 업그레이드

게임 오브젝트 활성 상태

Unity 4.0에서는 게임 오브젝트의 활성 상태가 처리되는 방법이 변경되었습니다. 이제 게임 오브젝트의 활성 상태가 자식 게임 오브젝트에 상속되므로, 게임 오브젝트가 활성 상태가 아니라면 자식 오브젝트도 활성 상태가 아닙니다. Unity 에디터는 이 새로운 동작이 이전 동작보다 더 합리적일 뿐만 아니라 오래전부터 항상 이렇게 동작했어야 했다고 믿습니다. 또한 새로 나올 GUI 시스템은 4.0 버전의 새로운 동작에 크게 의존하고 있고, 이렇게 동작하지 않는다면 새로운 GUI 시스템도 나올 수 없습니다. 하지만 새로운 Unity 4.0 동작과 함께 작동하도록 기존 프로젝트를 수정하는 작업이 다소 필요할 수 있으며, 변경 사항은 다음과 같습니다.

이전 동작:

  • 게임 오브젝트가 활성 상태인지 여부는 오브젝트의 .active 프로퍼티에 따라 결정되었습니다.
  • .active 프로퍼티를 사용하여 활성 여부를 쿼리하고 설정할 수 있었습니다.
  • 게임 오브젝트의 활성 상태는 자식 오브젝트의 활성 상태에 영향을 미치지 않았습니다. 게임 오브젝트와 모든 자식 오브젝트를 활성화하거나 비활성화하려면 GameObject.SetActiveRecursively 를 호출해야 했습니다.
  • SetActiveRecursively 를 게임 오브젝트에 사용할 때에는 자식 게임 오브젝트의 이전 활성 상태가 유실되었습니다. SetActiveRecursively 를 사용하여 게임 오브젝트와 모든 자식 오브젝트를 비활성화한 후 다시 활성화하면, SetActiveRecursively 호출 전에는 비활성 상태였던 자식 오브젝트가 활성 상태로 전환되었고, 자식의 활성 상태를 원래대로 복원하려면 직접 추적해야 했습니다.
  • 프리팹에는 활성 상태가 포함될 수 없었고, 프리팹 초기화 후 항상 활성 상태였습니다.

새로운 동작:

  • 게임 오브젝트가 활성 상태인지 여부는 자체 .activeSelf 프로퍼티와 모든 부모의 프로퍼티에 따라 정의됩니다. 게임 오브젝트와 모든 부모의 .activeSelf 프로퍼티가 true 라면 게임 오브젝트가 활성 상태가 됩니다. false 인 프로퍼티가 있으면 게임 오브젝트가 비활성 상태가 됩니다.
  • .activeInHierarchy 프로퍼티를 사용하여 쿼리할 수 있습니다.
  • GameObject.SetActive 를 호출하여 게임 오브젝트의 .activeSelf 상태를 변경할 수 있습니다. 이전에 활성 상태였던 게임 오브젝트에서 SetActive (false) 를 호출하면 해당 게임 오브젝트와 그 자식이 모두 비활성 상태로 전환됩니다. 이전에 비활성 상태였던 게임 오브젝트에서 SetActive (true) 를 호출하면 해당 게임 오브젝트와 그 부모가 모두 활성 상태로 전환됩니다. 부모가 모두 활성 상태이면(즉 부모의 .activeSelftrue 로 설정되어 있으면) 자식도 활성 상태입니다.
  • 즉, 활성 상태가 부모로부터 상속되므로 SetActiveRecursively 가 더 이상 필요하지 않습니다. 또한 SetActive 를 호출하여 계층 구조의 일부를 비활성화하고 활성화하면 자식 게임 오브젝트의 이전 활성 상태도 유지됩니다.
  • 프리팹은 프리팹 인스턴스화 시에 유지되는 활성 상태를 포함할 수 있습니다.

예제:

A, B, C라는 게임 오브젝트가 3개 있습니다. B와 C는 A의 자식입니다.

  • C.SetActive(false) 를 호출하여 C를 비활성화합니다.
  • 이제 A.activeInHierarchy == true, B.activeInHierarchy == true, C.activeInHierarchy == false 입니다.
  • 마찬가지로, A.activeSelf == true, B.activeSelf == true, C.activeSelf == false 입니다.
  • 이제 A.SetActive(false) 를 호출하여 부모를 비활성화합니다.
  • 이제 A.activeInHierarchy == false, B.activeInHierarchy == false, C.activeInHierarchy == false 입니다.
  • 마찬가지로, A.activeSelf == false, B.activeSelf == true, C.activeSelf == false 입니다.
  • 이제 A.SetActive(true) 를 호출하여 부모 A를 다시 활성화합니다.
  • 이제 A.activeInHierarchy == true, B.activeInHierarchy == true, C.activeInHierarchy == false 입니다.
  • 마찬가지로, A.activeSelf == true, B.activeSelf == true, C.activeSelf == false 입니다.

에디터에서의 새로운 활성 상태

이런 변경 사항을 시각화하기 위해, Unity 4.0 에디터에서 (자체 .activeSelf 프로퍼티나 부모의 해당 프로퍼티 중 하나가 false 로 설정되었기 때문에) 비활성화된 게임 오브젝트는 계층 구조에서 회색으로 표시되고 인스펙터에 회색의 비활성화된 아이콘으로 표시됩니다. 게임 오브젝트 자체의 .activeSelf 프로퍼티는 부모 상태에 관계 없이 토글할 수 있는 활성 체크박스로 표시됩니다. 하지만 모든 부모가 활성화되어 있을 때에만 게임 오브젝트가 활성화됩니다.

기존 프로젝트에 미치는 영향:

  • 코드의 어느 부분에서 이와 관련한 영향을 받는지를 알 수 있게 하기 위해 GameObject.active 프로퍼티와 GameObject.SetActiveRecursively() 함수가 지원 중단되었습니다.
  • 하지만 이 두 함수는 계속 작동합니다. GameObject.active 값을 읽는 것은 GameObject.activeInHierarchy 를 읽는 것과 같고 GameObject.active 를 설정하는 것은 GameObject.SetActive() 를 호출하는 것과 같습니다. GameObject.SetActiveRecursively() 를 호출하는 것은 게임 오브젝트와 모든 자식에서 GameObject.SetActive() 를 호출하는 것과 같습니다.
  • 3.5의 기존 씬은 씬에 있는 게임 오브젝트의 selfActive 프로퍼티를 이전의 active 프로퍼티로 설정하여 임포트됩니다.
  • 따라서 이전 Unity 버전에서 임포트되는 프로젝트는 비활성화된 오브젝트에 활성화된 자식이 없는 한(Unity 4.0에서는 더 이상 이렇게 존재할 수 없음) 계속 올바르게 작동하지만, 컴파일러 경고가 표시됩니다.
  • 프로젝트가 비활성화된 게임 오브젝트 아래에 활성화된 자식을 포함하고 있다면, Unity 4.0에서 작동하는 모델로 로직을 변경해야 합니다.

에셋 처리 파이프라인 변경 사항

4.0 개발 중에 성능, 메모리 사용량, 결정론을 개선하기 위해 에셋 임포트 파이프라인의 몇 가지 중요한 면을 내부적으로 변경했습니다. 이런 변경 사항은 대부분 사용자에게 영향을 미치지 않지만, 예외가 하나 있습니다. 에셋의 오브젝트는 임포트 파이프라인의 맨 끝에 도달할 때까지 영구적인 오브젝트가 되지 않고, 이전에 임포트된 에셋 버전은 완전히 대체됩니다.

첫 번째 부분은 포스트 프로세싱 중에 에셋의 오브젝트에 대한 올바른 레퍼런스를 가져올 수 없음을 의미하고, 두 번째 부분은 포스트 프로세싱 중에 수정 사항을 저장하기 위해 이전에 임포트된 에셋 버전에 대한 레퍼런스를 사용하면 해당 수정 사항을 잃게 됨을 의미합니다.

레퍼런스가 아직 영구적이지 않기 때문에 상실되는 예제

아래의 짧은 예제를 한번 살펴보십시오.

public class ModelPostprocessor : AssetPostprocessor
{
    public void OnPostprocessModel(GameObject go)
    {
        PrefabUtility.CreatePrefab("Prefabs/" + go.name, go);
    }
}


Unity 3.5에서는 모든 메시가 이미 영구적으로 전환되었기 때문에 메시 등에 대한 올바른 레퍼런스가 있는 프리팹이 생성되지만, Unity 4.0의 경우 그렇지 않으므로 동일한 포스트 프로세서에서 메시에 대한 모든 레퍼런스가 사라진 프리팹을 생성합니다. Unity 4.0은 아직 오리지널 모델 프리팹의 개체에 대한 레퍼런스를 확인할 줄 모르기 때문입니다. 모델 프리팹을 프리팹으로 올바르게 복사하려면 OnPostProcessAllAssets 를 사용하여 모든 인포트된 에셋을 살펴보고, 프리팹을 찾고, 위와 같이 새 프리팹을 생성해야 합니다.

이전에 임포트된 에셋에 대한 레퍼런스가 폐기되는 예제

두 번째 예는 조금 더 복잡하고, 3.5에서는 있었지만 4.0에는 해당되지 않는 사용 사례입니다. 다음은 메시에 대한 레퍼런스가 있는 단순 ScriptableObject 입니다.

public class Referencer : ScriptableObject
{
    public Mesh myMesh; 
}


ScriptableObject 를 사용하여 메시에 대한 레퍼런스가 있는 에셋을 모델 안에 만든 다음 포스트 프로세서에서 해당 레퍼런스를 선택하고 다른 이름을 지정합니다. 이 경우 모델을 다시 임포트하면 메시의 이름은 포스트 프로세서에서 결정한 이름이 되는 최종적인 결과로 이어집니다.

public class Postprocess : AssetPostprocessor
{
    public void OnPostprocessModel(GameObject go)
    {
        Referencer myRef = (Referencer)AssetDatabase.LoadAssetAtPath("Assets/MyRef.asset", typeof(Referencer));
        myRef.myMesh.name = "AwesomeMesh";
    }
}


Unity 3.5에서는 이렇게 해도 문제가 없었지만 Unity 4.0에서는 이미 임포트된 모델이 완전히 대체되므로 이전 임포트에서 메시 이름을 변경해도 아무런 영향이 없습니다. 이 경우 다른 수단으로 메시를 찾아 메시 이름을 바꿔서 문제를 해결할 수 있습니다. 더 중요한 사실은 Unity 4.0에서 포스트 프로세서에 주어진 입력만 수정하고 동일 에셋의 이전에 임포트된 버전에 의존하면 안 된다는 것입니다.

메시 읽기/쓰기 옵션

Unity 4.0에서는 “Read/Write Enabled” 옵션이 메시 임포트 설정에 추가되었습니다. 이 옵션을 끄면 Unity 에디터가 게임에서 메시 데이터 복사본을 언로드할 수 있으므로 메모리가 절약됩니다.

하지만 런타임 시점에 균일하지 않은 스케일로 메시를 스케일하거나 인스턴스화하는 경우 임포트 설정에서 “Read/Write Enabled”를 활성화해야 할 수 있습니다. 비균일 스케일링 시에는 메시 데이터를 메모리에 저장해야 하기 때문입니다. 일반적으로 이는 빌드 시간에 감지되지만, 메시가 런타임 시점에 스케일되거나 인스턴스화되는 경우 수동으로 설정해야 합니다. 그렇지 않으면 게임 빌드에 올바르게 렌더링되지 않을 수 있습니다.

메시 최적화

Unity 4.0의 모델 임포터에서는 메시 최적화가 더 개선되었습니다. Unity 4.0의 모델 임포터에서 “Mesh Optimization” 체크박스는 이제 기본적으로 활성화되어 있고, 성능을 최적화하기 위해 메시의 버텍스 순서를 변경합니다. 프로젝트에 메시의 버텍스 순서에 의존하는 포스트프로세싱 코드 또는 효과가 있을 수 있는데, 이 변경 사항으로 인해 깨져서 표시될 수 있습니다. 이 경우 메시 임포터에서 “Mesh Optimization”을 끄십시오. 특히 SkinnedCloth 컴포넌트를 사용하는 경우 메시를 최적화하면 버텍스 가중치 매핑이 변경됩니다. 따라서 3.5에서 임포트한 프로젝트에 SkinnedCloth를 사용하는 경우 영향을 받는 메시에 대해 “Mesh Optimization”을 끄거나 버텍스 가중치를 새 버텍스 순서에 맞게 다시 설정해야 합니다.

모바일 입력

Unity 4.0에서는 모바일 센서 입력의 얼라인먼트가 플랫폼 간에 개선되어 모바일 플랫폼에서 일반적인 입력을 처리할 때 코드를 더 적게 써도 됩니다. 이제 가속도 및 자이로 입력이 iOS 및 Android 플랫폼에서 모두 동일한 방법으로 화면 방향을 따릅니다. 이 변경 사항을 이용하려면 입력 코드를 다시 작성하고 가속도 및 자이로 입력을 처리할 때 플랫폼 및 화면 방향 관련 코드를 제거해야 합니다. iOS에서는 Input.compensateSensors 를 false로 설정하여 이전 동작을 계속 얻을 수 있습니다.

Unity 5.0의 기타 업그레이드 참고 사항
Unity 3.5로 업그레이드