반응형

출처 - http://docs.unity3d.com/Documentation/ScriptReference/index.Script_compilation_28Advanced29.html-

스크립트 컴파일 최적화 (Advanced)

유니티는 모든 스크립트를 .Net dll로 컴파일 합니다 .dll 파일들은 런타임에서 jit 방식으로 컴파일 됩니다.

이 방법은 빠른 속도의 스크립트 실행이 가능하도록 해줍니다이 방법은 기존 javaScript 대비 20배 정도 빠르고 native c++ 코드보다는 50%정도 느린 속도를 나타냅니다스크립트를 수정하고 저장하게 되면 유니티가 모든 스크립트를 컴파일 하는데 일정 시간이 걸리게 됩니다유니티가 컴파일을 진행하고 있는 경우유니티 메인 윈도우 오른쪽 아래 부분에서 작은 spinning progress icon을 확인하실 수 있습니다.

스크립트 컴파일은 다음의 4단계를 거쳐서 진행됩니다.

1. “Standard Assets”, “Pro Standard Assets” 또는 “Plugins”폴더 내에 있는 스크립트들이 가장 먼저 컴파일 됩니다.

위의 나열된 폴더 내의 스크립트들은 이 폴더 외부의 스크립트에 직접 접근할 수 없습니다.

해당 클래스나 변수에 직접 접근할 수는 없지만, GameObject.SendMessage 메소드를 통해서 통신을 할 수 있습니다.

2. “Starndard Assets/Editor”, “Pro Standard Assets/Editor” 또는 “Plugins/Editor”내의 스크립트들이 그 다음 순서로 컴파일 됩니다.

UnityEditor 네임스페이스를 사용하려는 경우에는 해당 스크립트를 반드시 위와 같이 “Editor”폴더 내부에 위치 시켜야 합니다예를 들어, menu item을 추가하거나 custom wizard를 작성하는 경우에는 위에 나열된 폴더 중 한 곳에 위치시켜야 합니다이 스크립트들은 1번의 그룹에 있는 스크립트에 접근이 가능합니다.

3. “Editor”폴더 외부의 스크립트들이 그 다음 순서로 컴파일 됩니다.

위의 단계에서 언급된 폴더 또는 “Editor”폴더 외부의 스크립트들이 그 다음 순서로 컴파일 됩니다.

이 단계에서 컴파일되는 스크립트들은 첫 번째 단계의 스크립트에 접근이 가능합니다 (“Standard Assets”, “Pro Standard Assets” 또는 “Plugins”). 이는 다른 스크립트 언어와 상호 운용이 가능하게 해줍니다예를 들어, C#스크립트를 참조하는 JavaScript를 작성하려는 경우, C# 스크립트를 “Standard Assets”폴더에 넣고 JavaScript는 “Standard Assets” 폴더 외부에 놓습니다.

이렇게 하면, JavaScript에서 C# 스크립트에 바로 접근이 가능합니다.

첫 번째 그룹에 속한 스크립트들은 컴파일 하는 데 시간이 더 많이 걸리게 됩니다첫 번째 그룹의 스크립트들이 컴파일 될 때세 번째 그룹의 스크립트들도 재 컴파일 되어야 하기 때문입니다따라서 컴파일 시간을 줄이고 싶은 경우변경이 거의 없는 스크립트는 첫 번째 그룹에 두고변경을 많이 해야 하는 스크립트는 세 번째 그룹에 둡니다.

4. “Editor”폴더 내부의 스크립트들이 그 다음 순서로 컴파일 됩니다.

UnityEditor 네임 스페이스를 사용하려는 경우, “Editor”폴더 내부에 해당 스크립트들을 넣어 두어야 합니다예를 들어, menu item을 추가하거나 custom wizard를 작성하는 경우에는 “Editor” 폴더에 위치시켜야 합니다.

여기에 위치한 스크립트들은 이전 그룹에 속한 모든 스크립트에 접근이 가능합니다.

게다가 WebPlayerTemplates 라는 이름의 폴더 내부에 위치한 스크립트들은  이상 컴파일 되지 않습니다.

 

유니티 버전에 따른 조건부 컴파일

유니티 2.6 버전부터 C# 전처리 define 구문이 추가되었습니다 define 구문들은 사용 중인 유니티 버전을 구별하고 이를 이용하면 버전에 따라 특정 기능에 조건부 접근이 가능합니다.

// Specific version define including the minor revision
#if UNITY_2_6_0
// Use Unity 2.6.0 specific feature
#endif

// Specific version define not including the minor revision
#if UNITY_2_6
// Use Unity 2.6.x specific feature
#endif

이 코드는 특정 유니티 버전에만 게임의 특정 기능이 동작하도록 할 때 사용할 수 있습니다 Define 구문이 유니티 2.6 버전부터 적용이 된다는 점을 주의해야 합니다스크립트에서 사용할 수 있도록 이 후의 유니티 버전에 해당하는 Define 구문이 적절하게 추가될 예정입니다.

플랫폼 별 조건부 컴파일에 대한 자세한 사항은 아래 링크를 참고하시기 바랍니다.

http://docs.unity3d.com/Documentation/Manual/PlatformDependentCompilation.html


반응형
반응형

- 출처 http://docs.xamarin.com/guides/ios/advanced_topics/limitations -


직접 번역한 글이기 때문에 오역과 매끄럽지 못한 부분이 있습니다.

너그러이 이해해주시기 바랍니다.


LImitation


Xamarin.iOS를 사용하는 아이폰 어플리케이션은 고정 코드로 컴파일이 되기 때문에, 런타임에서 코드를 생성하는 기능을 사용할 수 없습니다.


아래 항목들은 데스크탑 모노와 비교한 Xamarin.iOS의 제약사항들 입니다.


1. Limited Generics Support


기존 모노/.Net과 달리 아이폰에서 동작하는 코드는 JIT 컴파일러에 의해 컴파일되는 대신, AOT방식으로 정적으로 컴파일 됩니다.


모노의 Full AOT 기술은 Generic과 비교해서 몇가지 제한사항을 갖는데, 이는 Generic 기술이 컴파일 타임에 결정될 수 없는 부분이 있기 때문입니다. 이 문제는 일반 .Net 또는 모노 런타임에서는 항상 JIT 컴파일러를 사용하기 때문에 문제가 되지 않습니다.

하지만 Xamaric.iOS와 같은 정적(static) 컴파일러를 사용해야 하는 환경에서는 문제가 될 수 있습니다.


1.1 Generic virtual Methods


Generic 가상 메소드는 제한적으로 지원됩니다. 정적으로 모든 메소드의 감지가 불가능 하기 때문에 컴파일러는 이에 대한 지원을 몇가지로 제한하고 있습니다.

(c++에서 가상 템플릿 메소드를 지원하지 않는 이유도 이와 같습니다.)


Object나 String 같은 참조 타입을 사용해서 Generic 가상 메소드를 사용하는 것은 컴파일러에서 다룰 수 있는 부분이기 때문에 안전합니다. 하지만 여전히, 속도에 문제가 있기 때문에 Generic 가상 메소드의 사용을 피하시는 것이 좋습니다.


1.PNG

1.2 Large Value types


Xamarin.iOS는 6.3 버젼부터 크기가 작은 value 타입은 매끄럽게 실행될 수 있게 다른 방식으로 다루도록 되어 있습니다. 하지만, 크기가 큰 value 타입에는 아직 이 장점이 적용되지 못했습니다.

지금 시점에서, “크기가 작다”라고 고려될 수 있는 한계치는 12 바이트 입니다.

(또는 3 int / references)

2.PNG

1.3 Generic Value types


또다른 문제는 Generic value 타입을 사용할 때 입니다. 이 경우, generic 객체가 감춰지기  때문에 컴파일러가 필요한 시점에서 찾지 못하는 문제가 발생합니다.

3.PNG

위의 코드에서 컴파일러는 GenericMethod가 특별 관리가 되어야 한다는 점을 몰라서 일반 메소드와 동일하게 취급하게 됩니다.


이 제약사항은 Xamarin.iOS 6.3(preview)부터는 해당 value 타입의 크기가 작은경우에는 문제가 되지 않습니다.



1.4 No generic subclasses of NSObjects are allowed


Xamarin.iOS는 NSObject의 generic 서브클래스의 생성을 지원하지 않습니다.

아래 예제 코드에서 UIView가 NSObject의 서브클래스이기 때문에 동작하지 않습니다.

4.PNG

1.5 P/Invokes in Generic Types


Generic 클래스에서 P/Invoke 를 지원하지 않습니다.

5.PNG

1.6 Property.SetInfo on a Nullable Type is not supported


Nullable<T>에 값을 설정하기 위해서 사용되는 리플렉션 Property.SetInfo를 지원하지 않습니다.



1.7 Value types as Dictionary Keys


Value타입을 Dictionary<TKey, TValue>의 키로 사용하는 것은 문제가 많습니다. 기본적으로, Dictionary 생성자는 EqualityComparer<TKey>.Default를 사용하도록 되어 있고, EqualityComparer<TKey>.Default 는 리플렉션을 사용해서 EqualityComparer<TKey> 인터페이스를 구현하는 해당 타입을 객체화 하게됩니다.


이는 참조 타입에 대해서는 동작을 하지만 value 타입을 사용하는 경우, 장치에서 실행하려고 할 때 크래쉬를 발생시킬 수 있습니다.


해결책: 직접 EqualityComparer<TKey> 인터페이스를 구현하고, 해당 타입에 대한 객체를 Dictionary<TKey, TValue>(IEqualityComparer<TKey>) 생성자에 전달.



2. No Dynamic Code Generation


아이폰 커널에서 동적으로 코드생성하는 것을 지원하지 않기 때문에 아이폰에서 사용되는 모노에서도 동적 코드생성을 지원하지 않습니다.


  • System.Reflection.Emit 사용불가


  • System.Runtime.Remoting 미지원


  • 동적 타입 생성 미지원


  • 리버스 콜백의 경우 컴파일 타임에 반드시 등록되어야 함.



2.1 System.Reflection.Emit


System.Reflection.Emit 을 지원하지 않는다는 것은 동적 코드 생성을 필요로 하는 코드는 동작을 하지 않는다는 의미입니다.


이는 다음의 항목들을 포함합니다:


  • Dynamic Language Runtime.


  • Dynamic Language Runtime 위에서 빌드된 언어


  • Remoting의 TransparentProxy 또는 동적으로 코드를 생성해야하는 모든 항목.


중요: Reflection.EmitReflection을 혼동하지 마시기 바랍니다.

Reflection.Emit은 동적으로 코드를 생성하고, 해당 코드는 JIT로 컴파일되어야 하는 부분을 갖고 있는데, 아이폰에서 JIT 컴파일을 지원하지 않기 때문에, Reflection.Emit을 지원하지 않습니다.


하지만, Type.GetType(“someClass”), listing 메소드, listing 프로퍼티, fetching 어트리뷰트와 value를 포함한 전체 리플렉션 API는 정상 동작 합니다.



2.2 Reverse Callbacks


표준 모노에서 C# delegate 객체를 함수 포인터의 위치에 있는 관리되지 않는(unmanaged) 코드로 전달이 가능합니다.

주로 런타임에서 해당 함수 포인터들을 변환해서 unmanaged 코드가 managed 코드로 콜백을 전달할 수 있도록 합니다.


모노에서 이런 기능들은 JIT 컴파일러에 의해서 수행됩니다. AOT 컴파일러를 사용하게되면, 다음의 두가지 제약사항을 갖게 됩니다.


  • 모든 콜백 메소드에 대해서 MonoPInvokeCallbackAttribute 어트리뷰트를 체크해 줘야 합니다.


  • 메소드는 정적(static) 메소드여야 합니다. 다른 메소드는 지원하지 않습니다.


3. No Remoting


스택에 대한 remoting 기능을 지원하지 않습니다.



4. Runtime Disabled Features


아래 나열된 기능들은 모노 iOS 런타임 기능에서 제외된 항목들 입니다.


  • Profiler

  • Reflection.Emit

  • Reflection.Emit.Save 기능

  • COM 바인딩

  • JIT 엔진

  • Metadata verifier (JIT를 지원하지 않기 때문에 사용할 수 없음)


5. .Net API 제한사항


iOS에서 모든 .Net API를 사용할 수 없고, 제한 사항이 있습니다.

아래 FAQ 리스트를 확인하시기 바랍니다.

list of currently supported assemblies.


반응형
반응형
게임 오브젝트 풀 제작을 위해 게임 오브젝트 활성화/비활성화시 참고할 사항들을 정리해보았습니다.
관련 동작은 모두 4.2기준으로 정리하였습니다.

1. 계층 구조를 가진 게임 오브젝트 그룹의 활성화/비활성화
- 4.0부터는 편리하지만 느렸던.. SetActiveRecursively 함수가 사라지고 SetActive함수로 대체되었습니다. 하지만 이 함수는 지정한 단일 게임 오브젝트만 활성화/비활성화됩니다.
- 계층구조를 가진 게임 오브젝트 그룹을 모두 비활성화시키는 것을 4.0에서 간단히 구현하려면 비활성화된 게임 오브젝트를 미리 하나 만들고, 그룹을 이 게임 오브젝트의 자식으로 등록하면 그룹내 모든 게임 오브젝트가 자동으로 비활성화됩니다. 
그룹.transform.parent = 비활성화게임오브젝트.transform;
- 반대로 비활성화된 그룹을 활성화된 게임 오브젝트의 자식으로 옮기면 그룹 모두가 자동으로 활성화됩니다.

2. 게임 오브젝트의 활성화 및 비활성화시 일어나는 일들
- OnEnable/OnDisable 이벤트 함수가 호출됩니다.
- 게임 오브젝트가 비활성화되면 GameObject.Find 및 GameObject.FindObjectWithTag 등의 함수로는 찾을 수 없게 됩니다. 이는 유니티 내부에서 활성화된 게임 오브젝트만 목록으로 관리하기 때문입니다.
- 게임 오브젝트가 비활성화되면 컴포넌트에서 동작하던 코루틴 함수들은 모두 자동으로 종료됩니다. 
- 물체가 비활성화되면, 컴포넌트들의 실행은 중지되지만 데이터는 언제든지 바꿀 수 있습니다.
- Invoke와 Destroy의 시간 지연 명령은 게임 오브젝트가 비활성화되어도 중지되지 않습니다.

3. OnEnable과 Awake, Start와의 차이점
- OnEnable 함수는 Awake함수 이후와 Start 함수 이전에 호출되며, Awake, Start 함수와 다르게 비활성화한 후 활성화하면 다시 호출됩니다.
- OnEnable함수를 활용하여 아래처럼 코루틴을 동작시키는 코드를 만들면 게임 오브젝트의 활성화, 비활성화 걱정 없이 이전 상태의 코루틴을 유지할 수 있습니다.

public string state = string.Empty;
void OnEnable()
{
if(string.IsNullOrEmpty(state))
state = "Idle";
StartCoroutine(state);
}

4. 코루틴의 수동 활성화/비활성화
- 코루틴의 호출은 StartCoroutine(코루틴함수) 와  StartCoroutine("코루틴함수이름") 이 있습니다. 
- 전자는 수동으로 종료시킬 방법이 없지만, 후자는 StopCoroutine("코루틴함수이름") 으로 멈출 수 있습니다.
 StartCoroutine("코루틴함수이름") 을 여러 번 호출하여 동일한 코루틴을 여러개 실행시켜도 StopCoroutine("코루틴함수이름") 함수 호출 한 번이면 모두 없어집니다. 

5.스크립트 컴포넌트의 활성화 비활성화
- 게임 오브젝트가 아닌 스크립트 컴포넌트를 활성화 비활성화하는 경우에도 동일하게 OnEnable/OnDisable 함수가 호출됩니다.
- 하지만 이상하게도 스크립트 컴포넌트를 비활성화하면 게임 오브젝트를 비활성화시키는 경우와 다르게 코루틴은 죽지않고 그대로 유지됩니다.
- 따라서 이 경우에는 특별히 OnDisable 함수에 StopCoroutine 함수를 명시해주어야 합니다.

void OnDisable()
{
StopCoroutine(state);
}

6. 유니티 렌더링 루프의 동작방식
- 렌더링 루프는 정해진 순서대로 각 컴포넌트의 관리자들이 자신들이 가지고 있는 컴포넌트 목록을 체크하면서 현재 프레임에서 해야할 일들을 진행합니다. 
- 예를 들어 render.enable = false; 구문은 게임 오브젝트의 렌더러 컴포넌트를 렌더링 관리자의 관리 목록에서 제거합니다.
- 렌더링 작업에 대한 부하만 고려한다면 이는 가장 가볍고 빠른 활성화/비활성화방법입니다.
- 하지만 게임 오브젝트 내에 컴포넌트가 많다면, 각 컴포넌트의 관리자들이 쓸데없는 체크를 하지 않게 게임 오브젝트를 모두 비활성화하는 것이 좋을 수도 있습니다.


출처 : http://goo.gl/tKdoUS


반응형

'개발 Tip > Unity3D' 카테고리의 다른 글

유니티 스크립트 컴파일 (번역)  (0) 2013.09.27
모노 iOS 제약사항 (번역글)  (0) 2013.09.27
유니티 Tips ver 2013-09-25  (0) 2013.09.27
Unity3D 상에서 선긋기(Line)  (2) 2013.04.30
Sprite Manager 2 vs. 2D Toolkit  (0) 2013.04.05

+ Recent posts