1. IL2CPP

유니티 엔진의 내부는 C++로 구성되어있다.

따라서, 유니티가 C#을 사용하여 느리다 라는 것은 어느 정도 잘못된 말이지만

개발자 스크립팅 부분은 C#을 사용하였기에 아쉬운 점이 있던 것은 사실이다.

 

하지만, IL2CPP는 이런 유니티의 단점을 커버해준다.

IL2CPP는 Unity 프로젝트의 성능, 보안 및 플랫폼 호환성을 개선하는 등의 용도로 사용된다.

IL2CPP는 결과적으로 스크립팅 부분도 C++로 돌아가게끔 해주기 때문이다.

 

2. Mono

IL2CPP에 대해서 자세하게 알아보기 전에 몇가지 더 알아둬야 할 것이 있다.

본래 C#은 MS에서 윈도우 전용으로나 사용되던 언어였다. (현재는 .NET Core를 사용한다.)

 IOS나 안드로이드 같은 다른 환경에서는 .NET Framework가 구동되지 않았기 때문이었다.

 

크로스 플랫폼이 기본이 되어가는 어플리케이션 환경 속에서

이런 C# .NET의 단점은 너무나도 치명적이었다

이 단점을 보완하기 위하여 시미안(Ximian)이라는 곳에서 Mono 프로젝트가 오픈 소스로 공개되었고

Mono 프로젝트는 여러 플랫폼에서 .NET을 사용할 수 있게 해주었다.

현재는 MS에서 인수하여 개발을 진행하고 있다.

 

Unity 또한 게임 어플리케이션을 주로 개발하는데 사용하기에 Mono로 빌드하여 사용하였으나,

Mono 프로젝트가 오래되었고 IOS 환경에서 구동할 수 없는 치명적인 단점.

JIT(Just In Time) 방식의 컴파일러이기 때문에 유연하지만 느리다는 단점이 있어서 (게임은 퍼포먼스가 중요하다.)

IL2CPP라는 스크립팅 백엔드를 개발하게 된다.

 

3. IL2CPP의 특징

IL2CPP는 AOT(Ahead Of Time) 방식으로 구동된다.

말 그대로 소스 코드를 '미리' 컴파일 하는 방식으로 CIL을 C++로 미리 바꿔서 사용한다.

Mono의 JIT 방식은 코드를 CIL로 가지고 있다가 플랫폼에 맞춰 변환한다.

 

IL2CPP가 미리 컴파일 된 방식을 사용하는 만큼 속도 면에서 더 유리하다.

하지만, JIT 방식이 가지고 있던 핫 리로드와 같은 장점은 사용할 수 없다.

 

또한, IL2CPP로 빌드된 파일은 디컴파일로 코드를 제대로 확인하기 힘들어

어셈블리로 해석해야 하는 상황에 놓이기 때문에 최소한의 보안 역할도 할 수 있다.

Mono(JIT)와 IL2CPP(AOT)
패스트 런타임과 빌드도 선택할 수 있다.

4. IL2CPP의 구동 방식

IL2CPP의 구동 방식

 

  1. Unity 스크립팅 API코드를 일반 .NET DLL로 컴파일
  2. 관리되는 바이트코드 스트리핑을 적용 -> 빌드된 게임의 크기를 크게 줄여줍니다.
  3. 모든 관리되는 어셈블리를 표준 C++ 코드로 전환
  4. 생성된 C++코드와 IL2CPP의 런타임 부분을 네이티브 플랫폼 컴파일러로 컴파일
  5. 대상 플랫폼에 따라 실행 가능한 파일이나 DLL에 코드를 연결

더 간단하게 보면 아래의 그림과 깉이 될 것이다.

 

간략한 그림 설명

 

 

https://www.youtube.com/watch?v=-9X965jXrn8

 

1. 오클루전 컬링이란?

 

오클루전 컬링이란 다른 오브젝트에 의해 가려져서 카메라에 보이지 않을 때 (Occlusion)

해당 오브젝트의 렌더링을 비활성화 하는 기능이다.

 

기본적으로 카메라는 절두체(프러스텀) 컬링을 수행하여 카메라의 뷰 절두체에 속하지 않는 모든 렌더러를 제외한다.

하지만 절두체 컬링은 렌더러가 다른 게임 오브젝트에 의해 가려지는지를 확인하지 않으므로,

Unity가 최종 프레임에 표시되지 않는 렌더러에 대한 렌더링 작업에 CPU 및 GPU 시간을 여전히 낭비할 수 있다.

오클루전 컬링은 Unity가 이러한 낭비되는 작업을 수행하지 못하도록 방지한다.

 

  • 오클루더 : 다른 오브젝트를 가리는 역할. 사전 연산을 걸쳐서 데이터를 미리 Bake 해놓는다. 따라서 Static 오브젝트이다.
  • 오클루디 : 오클루더에 의해 가려지는 오브젝트.

 

2. 오클루전 컬링을 사용해야 할 때

 

  • 오클루전 컬링은 작고 윤곽이 또렷한 영역이 견고한 게임 오브젝트에 의해                                                                  서로 명확하게 분리된 씬에서 가장 잘 작동한다. (EX. 복도로 연결된 방)
  • 오클루전 컬링을 사용하여 동적 게임 오브젝트를 가릴 수 있지만, 동적 게임 오브젝트는 다른 게임 오브젝트를 가릴 수 없다. 프로젝트가 런타임 시점에 씬 지오메트리를 생성하는 경우에는 Unity의 빌트인 오클루전 컬링이 프로젝트에 적합하지 않다. (런타임 시 생성되는 장애물은 오클루전 적용이 불가능)
  • 야외 씬 같이 오브젝트끼리 가려지는 경우가 많지 않은 경우에는 오브젝트를 가림으로써 얻는 이득보다 오클루전 컬링 연산에 드는 비용이 더 클 수 있다.

 

한 마디로, 오클루전 컬링은 좁은 맵에서 움직이지 않는 견고한 장애물이 많을 때 효과적이다.

 

 

https://tsyang.tistory.com/84
https://docs.unity3d.com/kr/current/Manual/OcclusionCulling.html

 

 

 

'C# > Unity3D' 카테고리의 다른 글

[Unity3D] Mono, IL2CPP, AOT, JIT  (0) 2022.09.26
[Unity3D] 싱글톤 패턴 (Singleton Pattern)  (0) 2022.02.07
[Unity3D] 디펜던시 인젝션 (DI)  (0) 2022.01.27

1. Singleton 이란?

 

다른 클래스에서 공통적으로 많이 접근하는 클래스가 있을 경우 (ex GameManager) 

해당 클래스의 인스턴스(실체)를 하나로 유지하여 프로젝트에서 클래스의 데이터를 유지하고 객체를 단일화한다.

 

2. Unity에서 Singleton을 사용하는 이유

 

Manager류의 게임을 관리하는 오브젝트를 생성할 때 

인스턴스가 하나이기 때문에 데이터를 쉽게 유지할 수 있고,

정적 선언을 하기 때문에 그 유지된 데이터를 다른 클래스에서 쉽게 접근하여 사용이 가능하다.

 

3. 예제

 

public class GameManager : MonoBehaviour
{
	// static으로 정적 선언하여 프로그램이 끝날 때까지 유지하고 private하여 다른 클래스에서 수정할 수 없게 한다
    static GameManager _instance = null;

	// public 선언하여 다른 클래스에서 접근할 수 있게 하고 get 속성을 통해 접근만 가능하게 한다
    public static GameManager instance {
        get {
            if (_instance == null) {
                _instance = new GameManager();
            }
            return _instance;
        }
    }

	// MonoBehaviour를 상속받는 클래스가 인스턴스화 되는 과정을 막을 수 없으므로 Awake에서 null여부를 검사하여 예외처리를 한다
    void Awake() {
    	// 인스턴스가 비어있을 경우(막 생성되었을 때) 인스턴스를 this로 지정한다
        if (_instance == null) {
            _instance = this;
        }
        // 인스턴스가 비어있지 않을 경우(씬 이동 같은 경우로 인해 MonoBehaviour가 호출되어 인스턴스가 재생성 될 때) 재생성된 오브젝트를 파괴해준다
        else if (_instance != null) {
            Destroy(this.gameObject);
        }
        
        // 씬 로드시 해당 오브젝트를 파괴하지 않아야 다음 씬에도 유지가 된다
        DontDestroyOnLoad(this.gameObject);
    }
}

 

4. 이외의 방법

 

이외에도 MonoBehaviour를 상속받지 않고 사용하는 방법도 있다.

이 경우 하이어라키에 있는 인스턴스를 신경쓰지 않아도 되는 장점이 생긴다.

즉, 씬 이동시 인스턴스가 재생성 되는 과정을 신경쓰지 않아도 되니 Awake에서 다시 검사해주는 과정이 필요가 없다.

하지만, 말 그대로 메모리에만 존재하고 하이어라키에는 보이지 않아 인스펙터로 시각적으로 정보를 확인할 수 없다.

개발하는 입장에서 헷갈릴 수 있어 자주 사용하는 방법은 아니다. 

'C# > Unity3D' 카테고리의 다른 글

[Unity3D] Mono, IL2CPP, AOT, JIT  (0) 2022.09.26
[Unity3D] Occlusion Culling (오클루전 컬링)  (0) 2022.06.28
[Unity3D] 디펜던시 인젝션 (DI)  (0) 2022.01.27

1. Dependency Injection (의존성 주입)이란?

 

클래스 A가 어떤 작업을 수행하기 위해 클래스 B의 인스턴스에 의존해야 하는 경우,

B는 A의 디펜던시(의존성)이라고 한다.

 

Dependency Injection Pattern 줄여서, DI 패턴은 디펜던시를 따로 참조하지 않아도 주입해주는 기능을 한다.

 

// Case 1 (의존성이 있지만 스크립트 내에서 참조)
GameObject obj1;

void Awake() {
	obj = GameObject.Find("Player");
}

// Case 2 (유니티 인스펙터에서 접근하여 의존성을 주입)
public GameObject obj1;

// Case 3 (유니티 인스펙터에서 접근하여 의존성을 주입)
[Serializefield]
GameObject obj1;

 

 

2. 장점

 

Reduced Dependencies
- 종속성이 감소한다.
- components의 종속성이 감소하면 변경에 민감하지 않다.
More Reusable Code
- 재사용성이 증가한다.
- 일부 인터페이스의 다른 구현이 필요한 경우, 코드를 변경할 필요없이 해당 구현을 사용하도록 components를 구성할 수 있다.
More Testable Code
- 더 많은 테스트 코드를 만들 수 있다.
- Mock 객체는 실제 구현의 테스트로 사용되는 객체
종속성을 components에 주입할 수 있는 경우 이러한 종속성의 Mock 구현을 주입할 수 있다.
예를 들어, Mock 객체가 올바른 객체를 반환할 때, null을 반환할 때, 예외가 발생할 때 모두 처리한다.
More Readable Code
- 코드를 읽기 쉬워진다.
- components의 종속성을 보다 쉽게 파악할 수 있으므로 코드를 쉽게 읽을 수 있다.

참조 :

 

[Design Pattern] DI란 (Dependency Injection) - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

 

3. Zenject

 

Extenject Dependency Injection IOC | 유틸리티 도구 | Unity Asset Store

Use the Extenject Dependency Injection IOC from Mathijs Bakker on your next project. Find this utility tool & more on the Unity Asset Store.

assetstore.unity.com

Zenject를 통해 유니티에서 DI를 쉽고 기능적으로 사용할 수 있다.

'C# > Unity3D' 카테고리의 다른 글

[Unity3D] Mono, IL2CPP, AOT, JIT  (0) 2022.09.26
[Unity3D] Occlusion Culling (오클루전 컬링)  (0) 2022.06.28
[Unity3D] 싱글톤 패턴 (Singleton Pattern)  (0) 2022.02.07

+ Recent posts