할 건 해야지(250818)

Unity 게임개발 기술면접 5문항

문답

1. Addressables / Asset Management

질문:

Unity에서 Addressables 시스템을 사용할 때의 장점과 단점은 무엇이며, 원격 다운로드(예: CDN 배포)를 고려한 구조를 설계한다면 어떤 점을 유의해야 할까요?

답변:

직접 사용하면서 불편했던 단점은, 준비 할 게 많다는 것.
에셋 각각의 특성에 맞게 Key, Label 등을 하나하나 설정해주는 과정이 필요함. CDM 배포의 경우는 서버 설비를 필요로 함. 인게임 스크립트에서도 카탈로그와 에셋을 다운로드 받고, 로드 언로드 및 실사용하는 등 과정이 많아짐.
장점은 에셋만의 빌드를 따로 하여 배포하기 때문에 스토어에 게임 본체를 가볍게 올릴 수 있다는 점, 필요에 따라 에셋의 다운로드를 선택적으로 할 수 있다는 점, 업데이트가 용이하다는 점, 개발 중 에셋의 참조를 Key와 Label을 통하기에 에셋의 실제 경로에 구애받지 않는다는 점, 에셋을 로드 혹은 언로드를 관리할 수 있어 메모리 관리에 용이하다는 점.
준비 과정에 비해 장점으로 얻어가는 게 많다고 판단될 경우 프로젝트에서 바로 사용하면 좋을 것.

2. Update Loop / 성능 최적화

질문:

Update(), FixedUpdate(), LateUpdate()의 차이를 설명하고, 물리 연산과 카메라 추적을 구현할 때 각각을 어떻게 활용해야 하는지 설명해보세요.

답변:

Update문은 Frame 당 한 번씩 유니티 생명주기 내에서 실행됨. LateUpdate는 프레임이 끝나기 직전 즉 프레임 마무리 단계에서 실행되기에 후처리에 필요한 작업들을 포함시키면 용이함. 예를 들어 카메라 추적 위치는 타 연산이 모두 완료된 이후인 LateUpdate에 두는 것으로 연산 순서에 따른 어긋남을 방지해 유저에게 매끄럽고 올바른 장면을 보여주도록 하면 용이함.
FixedUpdate는 Frame 단위 처리가 아닌 일정한 시간 간격으로 실행되는 메서드이기에, Update문에서 Time.deltaTime으로도 커버가 안 되는 작업 등을 포함시키면 용이.
아마 물리연산 관련 처리는 FixedUpdate에서 진행하는 게 비교적 오류가 적은 퍼포먼스를 보여준다고 했던 것 같은데, 상세 내용에 대해서는 다시 확인 해 봐야 할 듯.

3. Memory / GC (Garbage Collection)

질문:

Unity에서 GC(가비지 컬렉션)가 자주 발생하면 어떤 문제가 생기며, 이를 최소화하기 위한 방법은 무엇인가요?

답변:

GC는 가비지가 쌓인 뒤 어느 순간 한꺼번에 정리하는 모습을 보임. 이 순간 게임이 잠시 멈칫하는 모습을 보이게 될 수 있음.
이를 최소화하기 위해선 게임을 구성하는 로직에서 가비지라는 부산물을 최대한 적게 만들도록 하는 것이 기본적인 방법임.
비교적 무거운 작업인 박싱/언박싱, 클래스 단위의 인스턴스를 많이 생성하고 버리기, Instantiate/Destroy의 잦은 사용 등이 많은 가비지를 유발하기에, 오브젝트 풀링 등으로 대체하도록 함.
GC 최소화를 위한 방안은 더 알아봐야 할 듯.

4. Physics & Collision System

질문:

OnTriggerEnter와 OnCollisionEnter의 차이를 설명하고, 모바일 게임에서 다수의 충돌을 효율적으로 처리하기 위한 방법은 무엇인가요?

답변:

OnTriggerEnter와 OnCollisionEnter은 Collider 간 접촉이 일어났을 경우 최초 한 번만 작동하는 매서드임.
OnTriggerEnter은 두 콜라이더 중 어느 한 쪽 또는 양 쪽의 Trigger 속성이 true일 경우 작동하고, OnCollisionEnter은 두 콜라이더 모두 isTrigger 속성이 false일 경우 즉 실제 충돌하는 충돌체일 경우 작동함.
Rigidbody의 필요 여부는 정확하진 않지만 충돌한 두 물체 중 하나 이상의 GameObject에 반드시 필요했던 것으로 기억.
모바일 게임에서 다수의 충돌을 효율적으로 처리하기 위한 방법으로는, 가능한 경우 Rigidbody의 충돌연산 빈도에 대해 Continuous 아래로 구성하여 처리하도록 하거나, 충돌체의 모양? 이것도 Mesh라고 부르던가 아무튼 이 모델을 최대한 단순한 것을 사용하기.
더 최적화 하자면, 충돌과 유사한 알고리즘을 사용하는 방식도 존재할 것이다. 탄막이 지나간 궤적 line과의 접촉 여부를 통해 피격 판정을 받도록 하는 등의.
충돌 관련한 최적화에 관해서는 이 이상으로는 떠오르는 게 없다.

5. Shader & Rendering

질문:

2D 게임에서 “투명한 AoE 장판”을 표시하려고 할 때, 단순 SpriteRenderer 사용과 Shader 기반 구현의 차이는 무엇이며, 성능과 연출 면에서 어떤 방식을 택할지 설명해보세요.

답변:

Shader에 관해서는 상상의 영역이 포함된 답변임을 양해 바람.
SpriteRenderer의 경우, 단순히 준비된 스프라이트나 애니메이션을 그대로 사용하거나 일부 가공하여 실제 GameObject로써 씬에 표시되는 것.
Shader의 경우도 준비된 스프라이트를 재료로써 사용할 수도 있고, 그 외에도 시간, 카메라에서 표시되는 위치, 각종 수식 등 훨씬 폭넓은 범위의 요소를 조건식이나 연산식에 포함하도록 하는 ShaderGraph를 활용하는 등 더 유연한 표현을 구성할 수 있음.
성능면에서는 아무래도 SpriteRenderer는 계산할 요소가 적어 압도적 우위를 가지지 않을까 예상되고,
Shader의 경우도 Graph까지 가지 않고 광원처리나 질감 정도만 수반되는 가벼운 작업만이라면 특별히 SpriteRenderer에 비해 엄청 경쟁력이 떨어지거나 그런 건 없지 않을까 예상되는데
문제는 Shader 아는 게 너무 적어서 진짜 되는 대로 적은 것이라는 것.
종종 프로젝트 진행 중 문제가 생길 경우 특히 오래된 에셋 패키지에 포함된 셰이더가 잘 작동하지 않을 경우 몇 셰이더 코드를 직접 열어보거나 편집하는 경우는 있었는데, 자세히 또 아는 건 없는 그런 상태.


챗봇 피드백

좋습니다 👍 지금 적어주신 답변은 “내가 실제로 사용해본 경험을 기반으로 대답한다”는 인상을 주기 때문에 면접에서 좋은 인상을 남길 수 있습니다. 다만 몇몇 부분은 불확실하게 적혀 있거나(“정확하진 않지만…”), 면접관 입장에서 듣기 애매한 표현이 섞여 있어서 보완하면 더 탄탄해질 수 있습니다. 아래에 피드백과 개선 포인트를 정리해드릴게요.

1. Addressables / Asset Management

  • 잘한 점: 실제 경험에서 느낀 불편함과 장점을 구체적으로 언급함 → 현실적인 답변.

  • 보완 포인트: “CDM → CDN” 오타 수정, “서버 설비 필요” 부분을 좀 더 구체적으로(예: 클라우드 스토리지 + CDN 조합).

  • 추가하면 좋은 부분:

    • 단점: 초기 셋업 복잡도, 카탈로그 관리 필요, 캐싱 이슈
    • 유의점: Catalog 버전 관리, 네트워크 끊김 대비 재시도, 다운로드 진행 표시(UX)

👉 개선된 짧은 예시:

단점은 초기 설정과 Key/Label 관리가 번거롭고, 카탈로그 업데이트/호환성을 항상 고려해야 한다는 점입니다. 장점은 앱 본체를 최소화하고, CDN을 통해 필요한 리소스만 온디맨드로 받을 수 있어 메모리와 배포 효율이 좋아진다는 점입니다. 설계 시에는 카탈로그 버전 관리, 캐싱 정책, 네트워크 오류 대비 UX를 유의해야 합니다.

2. Update Loop / 성능 최적화

  • 잘한 점: Update, LateUpdate, FixedUpdate의 개념을 정확히 설명함.
  • 보완 포인트: “Time.deltaTime으로도 커버가 안 되는 작업” → 좀 애매한 표현. 실제로는 deltaTime이 프레임 보정이긴 하지만 물리 연산은 FixedUpdate에 종속된다는 식으로 정리하면 더 명확.
  • 추가하면 좋은 부분: Update에서는 입력/논리, FixedUpdate에서는 물리, LateUpdate에서는 카메라/후처리라는 역할 분리가 핵심.

👉 개선된 짧은 예시:

Update는 프레임마다 실행되어 입력/게임 로직에 적합하고, FixedUpdate는 일정 간격으로 실행되기에 물리 연산에 적합합니다. LateUpdate는 모든 Update가 끝난 후 호출되므로 카메라 추적과 같이 다른 오브젝트 연산을 반영한 후 처리해야 하는 경우에 사용합니다.

3. Memory / GC

  • 잘한 점: GC가 왜 문제인지(멈칫 현상) 정확히 짚음.

  • 보완 포인트: “가비지라는 부산물을 최소화” → 조금 추상적. “할당과 해제를 줄이는 것”으로 더 명확히 표현.

  • 추가하면 좋은 부분:

    • string 처리 시 StringBuilder 사용
    • struct vs class 고려
    • Object Pooling으로 Instantiate/Destroy 최소화

👉 개선된 짧은 예시:

GC가 자주 발생하면 프레임 드랍 스파이크가 생깁니다. 이를 줄이기 위해서는 할당/해제를 최소화해야 하며, 문자열 연결 시 StringBuilder를 쓰고, 빈번한 Instantiate/Destroy는 오브젝트 풀링으로 대체하며, 박싱/언박싱을 피하는 구조로 설계하는 것이 좋습니다.

4. Physics & Collision System

  • 잘한 점: OnTriggerEnter와 OnCollisionEnter 차이를 잘 설명함.
  • 보완 포인트: “Rigidbody의 필요 여부는 정확하진 않지만…” → 불확실한 대답은 감점 요소. 정확히 정리: 최소 한쪽에는 Rigidbody 필요.
  • 추가하면 좋은 부분: 모바일 최적화 → Layer Collision Matrix, Collider 단순화, Broadphase 알고리즘(Unity는 내부적으로 AABB tree).

👉 개선된 짧은 예시:

OnTriggerEnter는 isTrigger가 true일 때, OnCollisionEnter는 실제 물리 충돌일 때 발생합니다. 두 경우 모두 최소 한쪽에 Rigidbody가 필요합니다. 모바일 최적화를 위해서는 Layer Collision Matrix를 활용해 불필요한 충돌을 배제하고, **Collider는 단순한 형태(Box, Sphere, Capsule)**를 사용하며, 경우에 따라 **물리 대신 수학적 판정(예: 탄막 라인 교차 판정)**으로 대체합니다.

5. Shader & Rendering

  • 잘한 점: SpriteRenderer vs Shader의 개념적 차이를 설명함.

  • 보완 포인트: “상상의 영역”이라는 표현 → 면접에서는 자신 없는 답변처럼 들릴 수 있음. 오히려 “많이 다뤄보진 않았지만 기본적인 차이는…” 정도로 완화.

  • 추가하면 좋은 부분:

    • SpriteRenderer는 단순 표시, Shader는 GPU 연산 기반으로 다양한 효과 가능
    • 성능은 Shader라고 무조건 느린 게 아니라, 오히려 GPU 오프로드 덕에 CPU 부담을 줄일 수도 있음

👉 개선된 짧은 예시:

SpriteRenderer는 단순히 스프라이트를 표시하기에 빠르고 단순합니다. Shader는 시간, 좌표, 수식을 기반으로 다양한 연출(예: 파동, 투명 마스킹, 애니메이션 효과)을 GPU에서 처리할 수 있습니다. 성능은 효과에 따라 다르지만, 오히려 GPU 연산으로 CPU 부담을 줄일 수 있어 AoE 같은 연출에는 Shader 기반이 더 적합할 수 있습니다.

총평

  • 강점: 실제 경험 기반 답변, 구조적 설명 능력 👍

  • 보완 필요:

    • “정확하진 않지만” → 제거 or 확신 있게 정리
    • 추상적 표현 → 구체적인 사례로 대체
    • 모르는 부분은 “제가 확인한 바로는 ~, 다만 더 깊게 공부가 필요합니다”처럼 겸손하게 표현