Carrot
본문 바로가기
Unity/멋쟁이사자처럼 부트캠프

[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(101일차) - [3D 게임] 맵 최적화 & Unity Profiler(프로파일러) 확인법

by 독기품은토끼 2025. 10. 21.
✅ 오늘의 학습 목표
1. 맵 최적화 마무리
2. Profiler(프로파일러) 학습

1. 맵 최적화

저번 시간에 Room끼리 이웃으로 연결해주는 작업을 해주었으니

이제는 Player의 위치에 따라 Room이 생성되는 스크립트를 작성해줄 것이다.

public class RoomManager : MonoBehaviour
{
    // ...

    private void Start()
    {
        var startRoomId = 0;

        var prefab = GetRoomPrefab(startRoomId);
        if (prefab != null)
        {
            var instance = Instantiate(prefab);
            rooms[startRoomId].roomInstance = instance;
        }
    }

    public void SetNeighborsRoom(int id)
    {
        var room = rooms[id];
        if (room == null) return;

        foreach (var neighbor in room.Neighbors)
        {
            if (!neighbor.roomInstance)
            {
                var prefab = GetRoomPrefab(neighbor.Id);
                if (prefab != null)
                {
                    neighbor.roomInstance = Instantiate(prefab);
                }
            }
        }

        if (currentRoom != null)
        {
            foreach (var neighbor in currentRoom.Neighbors)
            {
                if (neighbor != room && !room.Neighbors.Contains(neighbor) && neighbor.roomInstance)
                {
                    Destroy(neighbor.roomInstance);
                    neighbor.roomInstance = null;
                }
            }
        }
        currentRoom = room;
    }

    private GameObject GetRoomPrefab(int id)
    {
        //foreach (var roomPrefab in roomPrefabs)
        //{
        //    if (roomPrefab.Id == id)
        //    {
        //        return roomPrefab.Prefab;
        //    }
        //}

        var prefab = roomPrefabs.Find(x => x.Id == id);
        return prefab != null ? prefab.Prefab : null;
    }
}

 

게임이 시작될 때에는 id가 0인 방이(프리팹) 생성되도록 해주었고

생성된 룸에 근접한 이웃 룸도 같이 프리팹으로 생성되는 로직을 구현해주었다.

 

최적화를 위한 작업이니 Room이 근접하지 않을 경우에는 다시 룸이 삭제되도록 하는 기능도 넣어주었다.

 

using System;
using UnityEngine;

public class RoomController : MonoBehaviour
{
    [SerializeField] private int id;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            RoomManager roomManager = RoomManager.Instance;
            if (roomManager != null)
            {
                roomManager.SetNeighborsRoom(id);
            }
        }
    }
}

 

이제 Player가 어느 방에 있고 그 방은 어느방과 근접하는지 확인하고 생성할 수 있도록

RoomController 스크립트를 작성해주었다.

 

기존에 RoomManager는 싱글톤으로 구현해주었기에 Instance로 바로 접근이 가능하고

각 룸 프리팹에 Box Collider를 추가해주어 Player가 위치한 방을 체크하도록 해주었다. (충돌처리로)

 

 

컴포넌트 연결까지 다 완료되고 실행해보면

Player의 위치에 따라 방이 생성&삭제됨을 확인할 수 있다.

 

2. CPU & GPU 병목 확인

최적화는 목표한 하드웨어 사양에서 안정적인 프레임레이트를 확보하는 것이 목적이다.

 

단순히 프레임이 떨어진다고 무작정 수정하기보다
병목(bottleneck)의 원인을 정확히 파악해야 한다.

  • CPU 병목
    • 스크립트, 복잡한 로직, 과도한 드로우콜(draw call) 등
  • GPU 병목
    • 3D 모델, 셰이더, 머티리얼 등 그래픽 관련 요소


Profiler, Frame Debugger, Stats 창을 함께 사용해
프레임당 지연의 원인이 CPU인지 GPU인지 확인해보자.

 

1. Profiler (프로파일러)

 

병목 현상을 확인하기 위해 Unity에서 제공하는 프로파일러창을 활용해줄 것이다.

 

 

프로파일 창을 열어보면 좌측에 모듈별로 사용량/성능을 확인해볼 수 있다.

 

상단 그래프의 노란색 영역은 CPU의 프레임 소요 시간을 나타내고

한 프레임이 16 ~ 33ms 안에 처리되어야 원활한 플레이가 가능하다.

 

빨간색 막대(Highlights)가 나타나는 구간은 프레임 드랍이 발생한 구간으로

특정 시점에서 CPU 연산량이 급격히 증가했음을 보여준다.

 

하단의 Timeline 뷰에서는 각 함수나 시스템의 실행 구간을 색상 블록으로 표현한다.

프래임 내에서 메서드가 어떤 순서로 실행되었는지 확인할 수 있다.

 

 

Timeline 뷰 외에도 Hierarchy 뷰로도 확인할 수 있는데

여기서 프레임 드랍이 발생한 공간의 원인을 찾아볼 수 있다.

 

 

CPU 사용 프로파일러 모듈 - Unity 매뉴얼

CPU 사용 프로파일러 모듈은 애플리케이션에서 시간을 소비한 위치를 표시하는 차트를 제공합니다. 이 모듈은 애플리케이션이 시간을 소비하는 모든 주요 영역(예: 렌더링, 스크립트, 애니메이

docs.unity3d.com

 

자세한 사용법은 Unity 공식 문서에 잘 기록되어 있으므로 생략하겠다.

 

2. Memory Profiler

 

메모리 상태를 진단하기 위하여 패키지 매니저에서 Memory Profiler을 설치해주었다.

 

 

현재 상태를 스냅샷으로 촬영하게 되면

오브젝트별로 메모리 점유량을 확인할 수 있다.

 

지금 내 프로젝트에서는 Texture2D 항목이 427.4MB를 차지하며 전체 메모리의 가장 큰 비중을 차지하고 있는 것을 확인할 수 있었다.

Native Size: 210.4MB, Graphics Size: 217.0MB → GPU 메모리로도 상당한 용량이 전송되고 있음을 의미한다.

이는 게임 내 고해상도 텍스처나 불필요하게 큰 이미지 파일이 메모리 사용량을 압박하고 있음을 나타낸다.

 

 

Memory Profiler의 All of Memory 탭에서 GameManager 오브젝트의 메모리 점유 상태를 확인한 이미지이다.

우리가 GameManager 스크립트를 작성할 때 싱글톤으로 작성해주었기 때문에

인스턴스가 단 하나만 존재하고 있음을 확인할 수 있었다.

 

이런식으로 검색 기능을 활용해서 메모리 누수나 중복 생성 등을 확인할 수 있다.

 

3. Frame Debugger & Stats

 

Frame Debugger는 프레임 단위로 렌더링 이벤트(드로우콜)를 추적하는 도구이다.

Enable을 클릭하면 드로우콜이 진행되는 단계를 확인해볼 수 있다.

 

 

Game 뷰의 Stats 창에서는 현재 프레임의 렌더링 성능 지표를 확인할 수 있는데

Batches: 92, Saved by Batching: 0 → 배칭이 전혀 적용되지 않아 CPU 부하가 일어날 수 있음을 확인할 수 있었다.

 

이렇게 Frame Debugger는 렌더링 병목 구간을 식별하고,
Stats 창은 프레임레이트 저하의 원인(배칭, 드로우콜 등)을 수치로 파악하는 데 유용하다.

 

3. LOD

🥕 예행 작업
1. Asset 다운로드
 

3D Game Kit - Props Pack | 3D 소품 | Unity Asset Store

Elevate your workflow with the 3D Game Kit - Props Pack asset from Unity Technologies. Find this & other 소품 options on the Unity Asset Store.

assetstore.unity.com

 

LOD는 거리에 따라 3D 오브젝트의 디테일(폴리곤 수)을 다르게 표현하는 기술이다.

단계 설명 예시
LOD 0 가장 높은 디테일 (가까운 거리) 하이폴리곤 모델
LOD 1 중간 디테일 중간 해상도 모델
LOD 2 낮은 디테일 (멀리서 보일 때) 로우폴리곤 모델
Culled 너무 멀리 있을 때 아예 렌더링 안 함