본문 바로가기
정보/공부

[유니티]게임 클라이언트 최적화 5가지방법

by 용물 2025. 3. 29.
반응형

게임을 만들다 보면 성능이 애매하게 안 나오거나 프레임 드랍이 생기는 경우가 많다. 특히 유니티로 개발할 때는 최적화를 신경 써야 할 부분이 많다. 본인은 유니티 개발을 진행하면서, 몰랐던 부분 정리와 알고있던 부분도 새로 정리를 해보려고한다. 

1. 객체 풀링(Object Pooling) 활용하기

문제점

적이나 투사체 같은 오브젝트를 Instantiate()와 Destroy()로 계속 생성하고 삭제하면 성능 저하가 심해진다. 가비지 컬렉션이 자주 발생하면서 프레임 드랍이 생길 수도 있다.

해결책

  • 오브젝트 풀링(Object Pooling)을 사용하면 미리 생성한 객체를 재사용할 수 있다.
  • Queue<GameObject>나 List<GameObject>를 활용해서 비활성화된 오브젝트를 따로 보관했다가 필요할 때 꺼내 쓰고, 다시 돌려놓으면 된다.
  • 이런 방식으로 하면 불필요한 메모리 할당과 해제를 줄일 수 있다.
public class ObjectPool : MonoBehaviour
{
    public GameObject prefab;
    private Queue<GameObject> pool = new Queue<GameObject>();
    
    public GameObject GetObject()
    {
        if (pool.Count > 0)
        {
            GameObject obj = pool.Dequeue();
            obj.SetActive(true);
            return obj;
        }
        return Instantiate(prefab);
    }
    
    public void ReturnObject(GameObject obj)
    {
        obj.SetActive(false);
        pool.Enqueue(obj);
    }
}

2. 불필요한 Update 호출 줄이기

문제점

Update()는 프레임마다 호출되기 때문에 불필요한 연산이 많으면 성능이 급격히 떨어진다.

해결책

  • Update()에서 매 프레임 실행할 필요가 없는 로직은 InvokeRepeating(), Coroutine, Event 같은 걸로 대체하는 게 좋다.
  • FixedUpdate()와 LateUpdate()도 상황에 맞게 활용하면 불필요한 계산을 줄일 수 있다.
  • 특정 상황에서만 Update()가 실행되도록 관리하는 것도 좋은 방법이다.

3. 배치 렌더링(Batching) 최적화

문제점

Draw Call(그리기 호출)이 많으면 GPU 부하가 커지고, 결국 게임이 버벅이게 된다.

해결책

  • Static Batching: 정적인 오브젝트는 Static 체크를 해서 한 번에 렌더링하도록 설정한다.
  • Dynamic Batching: 작은 오브젝트끼리는 자동으로 묶어서 처리될 수 있도록 유니티에서 지원하는 기능을 활용한다.
  • GPU Instancing: 동일한 메쉬를 여러 개 렌더링해야 할 경우 Instancing을 적용하면 훨씬 효율적이다.

4. 메모리 관리 최적화

문제점

불필요한 객체 생성이 많거나 메모리 누수가 발생하면 게임 성능이 급격히 저하될 수 있다.

해결책

  • Resources.UnloadUnusedAssets()를 활용해서 사용하지 않는 리소스를 정리한다.
  • 텍스처와 애니메이션 클립은 필요 이상으로 크지 않게 조절하고 압축을 활용한다.
  • GC.Collect() 호출을 최소화하고, 가비지 컬렉션이 자주 발생하지 않도록 자료구조를 신중하게 선택한다. (List<T>, Dictionary<K,V> 등)

5. 물리 엔진 최적화

문제점

물리 연산이 많으면 CPU 사용량이 증가하고 성능 저하가 발생할 수 있다.

해결책

  • Rigidbody가 필요 없는 오브젝트는 Kinematic으로 설정한다.
  • Physics.OverlapSphere() 같은 광범위한 충돌 검사는 꼭 필요한 경우에만 사용한다.
  • FixedUpdate()에서 매번 물리 연산을 수행하기보다는, 필요한 순간에만 실행되도록 조절한다.

 

최적화는 한 번 하고 끝나는 게 아니라, 지속적으로 테스트하고 개선하는 게 중요하다. 다들 최적화 게임을 진행하기 위해 노력해보자 

반응형

댓글