반응형
1. 프로파일러를 이용해서 병목현상 체크하기.
 - Window > Profiler 메뉴를 이용한다.

2. 컬링 기법 이용하기.
 - 프러스텀 컬링 (Frustum Culling) : 레이어별로 컬링 거리를 따로 지정 가능하다.
 - 오클루전 컬링 (Occlusion Culling) : Window > Occlusion Culling 메뉴를 이용한다.

3. 드로우콜 체크하기.
 - 드로우콜은 게임 오브젝트에 설정된 재질의 셰이더 패스당 하나씩 일어난다.
 - 렌더러에 사용한 재질의 수만큼 드로우콜이 발생한다.
 - 드로우콜의 발생을 최소화하기 위해서는 성질이 동일한 물체들은 하나의 메쉬와 재질을 사용하도록 통합하는 것이다.
   (이를 위해 최상위 오브젝트에 사용할 수 있는 CombineChildren 컴포넌트가 Scripts 패키지에서 제공된다.)
 - CombineChildren 컴포넌트를 사용할 경우, 하위 오브젝트가 모두 하나가 되어서 빛의 계산을 모두 수행하는 등 불필요한 계산이 발생하는 단점도 있다.
 - 같은 셰이더를 사용하더라도 다른 텍스처를 사용하면 드로우콜이 증가한다.
 - 위와 같은 경우, 텍스처를 모두 합친 큰 텍스처(텍스처 아틀라스)를 만들어 서로 공유하면 드로우콜을 줄일 수 있다.

4. 배칭기능 사용하기.
 - Edit > Project Settings > Player 에서 설정.
 - 정적 배칭을 사용할 경우, static으로 설정된 게임 오브젝트에서 동일한 재질을 사용하는 물체가 있는 경우 자동으로 통합한다.
 - 정적 배칭을 사용할 경우, CombineChildren처럼 통합되는 오브젝트를 모두 하나의 커다란 메쉬로 만들어서 따로 저장하게 된다. (메모리 사용 증가)
 - 동적 배칭은 움직이는 물체를 대상으로 동일한 재질을 사용하는 경우, 자동으로 메쉬를 통합하여 드로우콜을 줄여주는 기능이다.
 - 동적 배칭은 계산양이 많으므로, 정점이 900개 미만인 오브젝트만을 대상으로 수행된다.

5. 권장 텍스처 사용하기.
 - 아이폰 (PowerVR) : PVRTC
 - 안드로이드 (Tegra) : DXT
 - 안드로이드 (Adreno) : ATC
 - 안드로이드 (공통) : ETC1

6. 오버드로우
 - 겹치는 부분의 픽셀을 다시 그리는 것을 오버드로우라고 한다.
 - 오버드로우를 줄이는 가장 좋은 방법은 큰 영역을 차지하는 물체를 먼저 그리도록 하는 것이다.

7. 물리엔진
 - 유니티에서는 물리 엔진 작업을 렌더링 작업과 별개로 수행한다.
 - 물리 엔진 작업은 FixedUpdate() 함수에서 수행되며, 0.02초로 매우 짧아서 FixedUpdate() 함수가 여러 번 수행된 후 Update() 함수가 호출된다.
 - 따라서 FixedUpdate() 함수의 코드에는 필요한 기능만 넣도록 한다.
 - 게임 진행에 문제가 없다면 Edit > Project Settings > Time 메뉴에서 FixedUpdate() 함수의 실행 주기를 늘리는 것도 좋다.

8. 충돌체의 이동
 - 리지드 바디가 없는 고정 충돌체를 움직이면 CPU에 부하가 발생된다.
 - 이 경우, 리지드 바디를 추가하고 IsKinematics 옵션을 준 후 움직이는 것이 좋다.

9. Maximum Allowed timestep 조절
 - 여타 요인으로 시스템에 부하가 걸려 지정된 시간보다 오래 멈출 경우, 물리 계산을 건너뛰도록 설정하는 기능.
 - Edit > Project Settings > Time 메뉴에서 설정.

10. Solver Iteration Count 조절
 - 물리 관련 계산을 얼마나 정교하게 할 것인지 지정. ( 높을수록 정교해진다. )
 - Edit > Project Settings > Physics 메뉴에서 설정.

11. Sleep 조절
 - 리지드 바디의 속력이 지정된 수치보다 작을 경우, 자동으로 휴면 상태에 들어간다.
 - Edit > Project Settings > Physics 메뉴에서 설정.
 - Physics.Sleep() 함수를 이용해서 강제 휴면 상태를 만들 수도 있다. 
   (Awake()함수에서 사용하면 레벨이 로딩되기 전까지 물리 엔진 사용을 자제시킬 수 있다.)

12. 유니티 라이브러리 사용 시 주의사항
 - 유니티의 핵심기능은 모두 c++로 작성되어 있다.
 - 예를 들어 transform.position 에서 transform은 c#의 속성으로 정의되어 있고 position은 c++영역에 작성되어 있다.
 - 때문에 transform.position 구문을 자주 사용하는 것보다 미리 변수에 저장해두고 사용하는 방식이 좋다.
 - FindObject 계열 함수들은 매우 느리다. ( 미리 찾아서 저장해두는게 좋다. )
 - Instantiate 와 Destroy 함수를 이용한 프리팹의 생성과 소멸은 비용이 크다. ( 활성화와 비활성화를 이용하는 것이 좋다. )
 - 가급적이면 Update 함수보다 CoRoutine 함수를 사용하도록 한다.
 - 박싱과 언박싱은 부하가 큰 작업이다.
 - 나눗셈보다는 곱셈이 몇십배 빠르다.
 - magnitude 보다 sqrMagnitude를 사용해서 제곱근 계산을 줄이도록 한다.
 - 삼각함수의 값은 상수로 저장해두고 사용하는 게 좋다.
 - 고정 문자열은 readonly 혹은 const 키워드를 사용하여 가비지 컬렉션으로 부터 벗어나도록 한다.

13. 배열 관리
 - Array : 아이템들의 크기가 일정하고, 순서가 변할 일이 없다면 일반 배열을 사용하는 것이 가장 빠르게 동작한다.
 - ArrayList : 아이템들의 크기가 자주 변하고 순서도 자주 바뀌는데다, 모든 아이템이 레퍼런스형일 경우 사용한다.
 - List<T> : ArrayList인데 저장하는 데이터가 밸류 타입이면 제네릭 List를 사용해야 박싱이 일어나지 않는다.
 - Hashtable : 키와 값으로 구성된 사전류의 데이터를 관리할 때 해시 테이블을 사용하면 편리하다.
 - Dictionary<K, V> : 해시 테이블과 동일한 기능을 수행하나, 데이터의 형식이 밸류 타입이면 제네릭 Dictionary를 사용해야 박싱이 일어나지 않는다.

출처 : http://www.uzoo.in/?mid=master_codesnippet&order_type=desc&document_srl=539&listStyle=viewer#


반응형
반응형

출처 - 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


반응형
반응형
게임 오브젝트 풀 제작을 위해 게임 오브젝트 활성화/비활성화시 참고할 사항들을 정리해보았습니다.
관련 동작은 모두 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