본문 바로가기

전체 글

(65)
Unity 게임 최적화는 코드보다 데이터에서 시작하는 걸까? Unity에서 최적화 관련 내용을 공부하다 보니 코드를 최적화 한다는게 정확하게 무엇을 의미하는걸까 라는 호기심이 생겼다. 연산 자체를 줄이거나 호출하는 함수의 숫자를 줄이는게 코드 최적화인가 아니면 다른 무언가 있을까?그래서 여러 최적화 관련 글을 찾아보다 보니 공통적으로 나오는 이야기가 있다.최적화는 느린 코드를 빠르게 만드는 것보다시스템이 해야 하는 일 자체를 줄이는 것에서 시작한다.그리고 이 이야기는 자연스럽게 Data-Oriented Design, 즉 데이터 중심 설계와 연결된다.이번 글에서는 Jason Booth의 My approach to optimization과 Noel Llopis의 Data-Oriented Design 글을 참고해서 내가 이해한 방식으로 정리해보려고 한다.먼저 코드보다 ..
Unity Mono, IL2CPP,CoreCLR 을 알아보자 이번에 https://www.youtube.com/watch?v=DjjqDi6AOl8 해당 영상을 보면서 Unity가 CoreCLR 도입을 준비하고 있다는 사실을 알게 되었다.영상에서는 CoreCLR이 기존 Unity 런타임보다 현대적인 기능을 제공하고, 관리 코드의 실행 성능과 개발 환경을 개선할 가능성이 있다고 설명한다.하지만 내용을 이해하려다 보니 한 가지 궁금증이 생겼다.CoreCLR은 정확히 무엇이며, Unity에서 지금까지 사용해 온 Mono와 IL2CPP는 어떤 역할을 하는가?Unity에서 작성한 C# 코드는 그대로 CPU에서 실행되는 것이 아니다. 먼저 중간 언어인 IL 코드로 컴파일된 뒤, Mono, IL2CPP, CoreCLR과 같은 스크립팅 백엔드를 통해 플랫폼에서 실행할 수 있는 기..
Unity 오버드로우 이해와 최적화 방법 Unity에서 화면을 렌더링할 때 성능을 떨어뜨리는 대표적인 원인 중 하나가 오버드로우다.오버드로우는 특히 반투명 스프라이트, 파티클, 복잡한 UI, 포스트 프로세싱이 많은 장면에서 자주 발생한다.오버드로우가 심해지면 GPU가 실제 화면에 보이는 픽셀 수보다 훨씬 많은 픽셀을 반복해서 처리하게 된다.이러한 상태가 지속되면 GPU 처리 시간이 증가하고, 결국 GPU Bound 현상으로 이어질 수 있다.이번 글에서는 오버드로우가 무엇인지, 왜 발생하는지, Unity의 배치 처리와는 어떤 관계가 있는지, 그리고 어떤 방법으로 최적화할 수 있는지 정리해보았다.오버드로우란 무엇인가오버드로우는 한 프레임을 렌더링하는 과정에서 동일한 화면 픽셀이 두 번 이상 그려지는 현상이다.예를 들어 화면의 특정 픽셀에 배경이 먼..
Unity UI OBB 충돌 검사와 Burst를 이용한 최적화 Unity에서 UI 요소끼리 충돌하거나 겹치는지를 확인할 때는 보통 RectTransform의 영역을 기준으로 검사한다.UI가 회전하지 않은 상태라면 단순한 사각형 영역 비교만으로도 충분한 경우가 많다.하지만 UI가 회전되어 있다면 단순히 x, y, width, height만 비교하는 방식으로는 정확한 충돌 결과를 얻기 어렵다.예를 들어 정사각형 이미지가 45도 회전되어 있다고 생각해보자.화면에 보이는 이미지는 기울어져 있지만, 일반적인 축 정렬 사각형을 기준으로 충돌 영역을 계산하면 실제 이미지보다 더 넓은 영역이 충돌 영역으로 포함될 수 있다.이러한 문제를 해결하기 위해 사용할 수 있는 방식이 OBB다.OBB란 무엇인가OBB는 Oriented Bounding Box의 줄임말이다.일반적인 사각형 충돌 ..
Unity GC를 호출했는데 왜 메모리가 바로 줄어들지 않을까? Unity에서 메모리 프로파일링을 하다 보면 이런 상황을 자주 보게 된다.객체를 많이 생성하면 메모리 사용량이 증가한다.그리고 더 이상 사용하지 않으려고 참조를 끊고 GC.Collect()를 호출한다.그런데 이상하게도 메모리 사용량이 바로 줄어들지 않는 경우가 있다.분명히 객체는 더 이상 사용하지 않는데, 왜 Unity Profiler나 OS 메모리 사용량은 그대로 남아 있을까?이를 이해하려면 메모리를 하나의 큰 덩어리로 생각하면 안 된다.메모리는 하나의 큰 통이 아니라, 여러 개의 박스처럼 나뉘어 관리된다.예를 들어 A박스, B박스, C박스가 있다고 생각해보자.우리가 메모리 10만큼을 처음 할당한다고 해서 시스템이 정확히 10만큼만 가져오는 것은 아니다.Unity의 GC는 관리형 객체를 저장하기 위해 ..
Unity Update에서 LINQ와 람다식 사용을 조심해야 하는 이유 Unity 최적화 관련 글을 보다 보면 이런 이야기를 자주 보게 된다.Update나 자주 실행되는 함수에서는 LINQ 사용을 지양하라. 처음 들으면 조금 이상하게 느껴질 수 있다.LINQ와 람다식은 C#에서 굉장히 편리한 기능이다.코드를 짧고 읽기 쉽게 만들어주고, 복잡한 데이터 처리도 “무엇을 하고 싶은지” 중심으로 표현할 수 있게 해준다.예를 들어, 여러 적 중에서 살아있는 적만 찾는다고 해보자.일반적인 방식이라면 모든 적을 순회하면서 직접 조건을 검사할 수 있다.List aliveEnemies = new List();foreach (var enemy in enemies){ if (enemy.IsAlive) { aliveEnemies.Add(enemy); }}LINQ를 사..
Unity 비어 있는 Update는 왜 지워야 할까? 작업을 하다 보면 “비어 있는 Update는 제거해야 한다”는 이야기를 자주 듣게 된다.처음에는 조금 의문이 들 수 있다.void Update(){}아무 코드도 없는데, 이게 정말 성능에 영향을 줄까?단순히 비어 있는 함수 하나가 존재하는 것뿐인데 왜 굳이 지워야 한다고 하는 걸까?이번에는 Unity에서 Update가 어떻게 호출되는지, 그리고 왜 비어 있는 Update도 제거하는 것이 좋은지 알아보자.Unity는 매 프레임 리플렉션으로 Update를 찾지 않는다먼저 오해하기 쉬운 부분이 있다.Unity가 매 프레임마다 모든 MonoBehaviour를 리플렉션으로 검사하면서 Update 함수가 있는지 찾는 것은 아니다.Unity는 스크립트가 처음 로드되거나 사용될 때, 해당 MonoBehaviour가 어..
Unity 공간분할트리 using System.Collections.Generic;using UnityEngine;using Random = UnityEngine.Random;public class TreeData{ // 현재 영역의 Level public int level = 0; public int maxValue = 2; public int currentValue = 0; public Rect area; public List nodeList; // 다음 Level의 영역을 생성한다. public void NextLevelNode() { if (nodeList != null) return; nodeLis..