게임엔진 26

엔진 지원 시스템

시스템 클래스 생성 게임에서 사용되는 각종 매니저와 같은 싱글톤 혹은 정적 클래스들은 어떻게 생성하고 파괴해야 할까? 이런 클래스들을 생성/파괴할 때는 클래스들끼리의 의존성을 고려해야 한다. 유일한 클래스를 생성하는 메서드를 정의한 다음 의존성에 맞게 호출. //class RenderManager //... static RenderManager& get() { static RenderManager sSingleton; return sSingleton; } RenderManager() { VideoManager::get(); TextureManager::get(); //... } //... 그러나 위와 같은 방법은 아래와 같은 단점이 있다. 파괴 순서를 제어할 수 없어 파괴 과정에서 의존성이 훼손될 수 있..

게임엔진/일반 2024.02.11

IL2CPP가 Virtual Call과 Boxing을 처리하는 방법

이 글의 정보들은 2016년에 작성된 글을 기반으로 함. 따라서 2023년 현재 바뀐 부분이 있을 수 있음. Devirtualization 당연한 얘기지만, Virtual Call은 Direct Call보다 더 느리다. 따라서 일부 컴파일러는 Virtual Call을 Direct Call로 바꾸는 Devirtualization 기법을 사용하기도 한다. 단, 해당 코드가 컴파일 타임에 어떤 메서드를 실행시킬지를 판단할 수 있어야 한다. 이는 IL2CPP도 마찬가지이다. 다만 IL2CPP는 최적화에 보수적이기 때문에... var dog = new Dog(); //Dog는 Animal 클래스를 상속함. dog.Speak(); 위와 같은 상황에서도 Virtual Call을 호출하는 C++코드를 만들어낸다. (2..

(협업) Unity Accelerator - 임포트 시간 단축

에셋 임포팅 에셋 데이터는 CPU GPU등의 하드웨어에서 즉시 쓰일 수 있는 포맷일 필요가 있다. 그러나 대부분의 파일 포맷은 저장공간을 최소화하도록 되어있다.(압축) 따라서 유니티는 저장공간에 있는 데이터를 에셋 데이터로 컨버전 한다. 그리고 이렇게 변환된 에셋 데이터는 라이브러리 폴더에 캐싱된다. 이 과정을 에셋 임포팅이라 한다. 문제는? 근데 에셋 임포팅은 오래 걸림. 변경이 많으면 많을수록 더 오래걸린다. 만약 아예 모든 에셋을 임포트 해야 하는 상황이거나 플랫폼을 바꿔야 하는 경우라면 더욱 더 오래걸린다. 그러면 이걸 어떻게 해결할까? 임포트된 에셋 데이터는 라이브러리에 캐싱된다. 따라서 팀내에서 라이브러리 폴더를 공유할 수 있다. 플랫폼 스위칭 같은 경우를 대비하여 플랫폼별로 라이브러리 폴더를..

Update()

Update()는 어떻게 실행되나? Monobehaviour을 상속한 클래스 내에서 Update() 메서드를 정의하면 해당 메서드는 매 프레임마다 유니티에 의해 실행된다. 그럼 어떻게? Update()메서드를 private로 선언하건, protected로 선언하건 항상 수행되는 것을 보면 리플렉션 따위를 써서 메서드 이름을 얻어오고 어딘가에 캐싱한 다음 매 프레임마다 호출할 것으로 예상해볼 수 있다. 이게 아무것도 없는 빈 Update()메서드를 정의하지 말아야 하는 이유이기도 할 것이다. Update()의 성능은? 10000개의 Monobehaviour 객체를 매 프레임 업데이트 하고 싶다고 하자. 이 때 두 가지 방법이 가능하다. 하나는 Monobehaviour에 Update()를 정의하는 것. pr..

(토막상식) NativeContainer

Native Container Native Container는 native memory(unmanage)에 대한 wrapper이다. (Thread-Safe를 지원) native memory에 대한 버퍼를 managed code영역으로 노출하는 array, map, set등을 가지고 있음. 기본적으로는 Safety-Check를 수행하는데, unsafe로 시작하는 애들은 안 함. 그래서 당연히 native를 쓰는 게 더 좋겠지만 Native Container안에 Native Container를 담을 수는 없어서 unsafe를 써야 할 때가 있긴 하다. Access 정해주기 기본적으로 job 따위가 NativeContainer 인스턴스에 접근하면 read/write 둘 다 가능함. 그러나 이건 비효율적인데 r..

(토막상식) 유니티 메모리

메모리 종류 Managed Memory : GC가 적용되는 유저 영역의 메모리 레이어. Umanaged Memory(C#) : GC가 적용되지 않는 메모리 레이어, Unity.Collections 패키지를 통해 사용할 수 있는 공간이다. Native Memory(C++) : 유니티 엔진이 돌아갈때 쓰는 C++ 메모리이다. 일반적으로 유저가 접근 불가능한 영역. Managed Memory Mono나 IL2CPP나 VM에 managed memory 시스템이 있다. (=scripting memory system). managed heap : VM이 자동으로 GC써서 컨트롤 해주는 힙 메모리 영역. 여기에 메모리 할당하는걸 GC Allocation이라고도 한다. scripting stack : 그냥 스택영역....

유니티/DOTS2D Sprite Animation (1) - 핵심 구현 아이디어

2023.03.19 - [유니티/DOTS] - 2D Sprite Animation (0) - 레퍼런스 조사 2D Sprite Animation (0) - 레퍼런스 조사 DOTS로 3D 애니메이션의 구현은 레퍼런스가 꽤 많다. 에셋스토어만 봐도 꽤 완성된 패키지를 팔기도 함... 반면 2D 애니메이션쪽은 쫌 레퍼런스가 적다. 그나마 있는애들도 Entites 1.0 적용 이전이라 tsyang.tistory.com 공통 이전 레퍼런스에서 크게 두 가지를 조사했는데, https://youtu.be/t1f8ZreCuuQ https://forum.unity.com/threads/1-million-animated-sprites-at-60-fps.811116/ 1 MILLION animated sprites at 60..

게임엔진/DOTS 2023.04.02

2D Sprite Animation (0) - 레퍼런스 조사

DOTS로 3D 애니메이션의 구현은 레퍼런스가 꽤 많다. 에셋스토어만 봐도 꽤 완성된 패키지를 팔기도 함... 반면 2D 애니메이션쪽은 쫌 레퍼런스가 적다. 그나마 있는애들도 Entites 1.0 적용 이전이라 내가 고쳐서 써야한다. 우선 초반 레퍼런스로 보기 좋은 게 있다. 유튜버 Code Monkey의 Unity ECS 애니메이션 관련 영상 https://www.youtube.com/watch?v=tvi44I_SK3w 대충 아래와 같은 Graphics.DrawMesh를 통해 Sprite를 그려준다. 메테리얼은 아래와 같이 4개의 이미지로 구성된 Sheet이고 ... 위 코드와 같이 UV좌표로 잘라서 한 프레임씩 보여주는게 핵심 원리이다. 결국 애니메이션 정보도 별도 컴포넌트로 분리한 다음 몇 프레임에..

게임엔진/DOTS 2023.03.19

Unity.Physics에 가속도와 힘 구현해보기 - 2

2023.02.18 - [유니티/DOTS] - Unity.Physics에 가속도와 힘 구현해보기 - 1 Unity.Physics에 가속도와 힘 구현해보기 - 1 2023.02.10 - [유니티/DOTS] - Physics 1.0 써보기 주의 : 개인적으로 시행착오 겪으며 구현해 보는 것이니 신뢰 ㄴㄴ , 주절거리는 글임 개요 Unity.Physics에서는 속도에 따른 Transform 계산과 각종 충돌 계산 tsyang.tistory.com 오류 수정 이전 글에서 내가 구현한 가속도로 중력을 만들었을 때 유니티 physics의 중력보다 더 빠르게 움직이는 현상이 있었다. 처음엔 시스템 업데이트 순서가 잘못됐거나 버그로 여겼는데 아니었다. SystemAPI.Time.fixedDeltaTime이 당~연히 P..

게임엔진/DOTS 2023.03.12

ECS - RequireForUpdate / Dependency

2023.02.25 - [유니티/DOTS] - Entities - 컴포넌트 구조 RequireMatchingQueriesForUpdate Entites에는 RequireMatchingQueriesForUpdate 라는 어트리뷰트가 존재한다. 이걸 시스템에 달아주고, ISystem이나 SystemBase를 상속한 class/struct의 OnCreate에 위 두 가지 메서드를 호출해주면 해당 시스템은 매칭되는 Entity가 있을 경우에만 업데이트 된다. 위와 같은 방식으로 쓴다. Dependency Entities 샘플 코드를 보다 보면 위와 같이 dependency 설정을 해주는 코드들이 많다. SystemState는 현재 월드의 상태가 전달된다고 보면 된다. 여기서 state.Dependency는 현재..

게임엔진/DOTS 2023.03.05