public class Player : MonoBehaviour
{
void Update()
{
GetComponent<Health>().Regen();
}
}
public class PlayerController : MonoBehaviour
{
void Move() { }
void Attack() { }
void Jump() { }
void Heal() { }
void OpenInventory() { }
void SaveGame() { }
void UpdateUI() { }
}
public class A : MonoBehaviour
{
[SerializeField] B b;
}
public class B : MonoBehaviour
{
[SerializeField] A a;
}
void OnTriggerEnter(Collider other)
{
TankHealth health = other.GetComponent<TankHealth>();
if (health != null)
{
health.TakeDamage(10);
}
}
public class Health : MonoBehaviour
{
[SerializeField] UIManager ui;
void TakeDamage(int damage)
{
hp -= damage;
ui.UpdateHealthBar(hp);
}
}

면접 정답지
정의:
기능을 독립된 블록으로 나눠서 조립하는 설계 방식입니다.
핵심:
예시:
상속: Player → Character (코드 수정)
컴포넌트: GameObject + Move + Attack (조립)
실무:
Unity는 이미 컴포넌트 패턴 엔진이므로 자연스럽게 적용됩니다.
상속 (Inheritance):
조합 (Composition):
실무:
컴포넌트 패턴(조합)이 확장/재사용에 유리합니다.
Unity = 컴포넌트 패턴 엔진
매핑:
실무:
Transform, Rigidbody, Collider 모두 컴포넌트입니다.
1. 재사용성
2. 확장성
3. 유지보수성
실무:
팀 협업 시 서로 다른 컴포넌트 작업 → 충돌 최소화
이유:
확장성과 결합도 감소
효과:
실무:
인터페이스로 추상화하면 확장이 무한대로 가능합니다.
이유:
직접 참조를 끊기 위해
효과:
실무:
이벤트로 발행자-구독자를 완전 분리합니다.
성능:
TryGetComponent가 약 2배 빠름
차이점:
실무:
충돌/트리거 처리는 90% TryGetComponent 사용
1. 직접 참조 (단방향)
필수 의존성에 사용
2. 이벤트 (느슨한 결합)
알림/브로드캐스트에 사용
3. 인터페이스 (추상화)
확장 가능한 타입에 사용
실무:
정의:
너무 많은 일을 하는 컴포넌트 (안티패턴)
문제:
해결:
MoveComponent, CombatComponent, HealthComponent로 분리
판별:
100줄 넘거나 책임 3개 이상이면 분리
정의:
A가 B를 참조하고, B가 A를 참조
문제:
둘 다 독립 사용 불가
해결 1: 이벤트
A는 이벤트 발행만, B는 구독만
해결 2: 인터페이스
추상에 의존하여 단방향으로 만들기
실무:
이벤트/인터페이스로 단방향 의존으로 만듭니다.
정의:
한 클래스는 하나의 책임만
변경 이유:
1개 클래스 = 1개 변경 이유
예시:
MoveComponent - 이동만
ShootComponent - 공격만
HealthComponent - 체력만
효과:
실무:
컴포넌트 하나는 한 가지만 하게 합니다.
정의:
확장에는 열림, 수정에는 닫힘
의미:
새 기능 추가 시 기존 코드 수정 불필요
예시:
인터페이스로 새 타입 추가해도 기존 코드 수정 안 함
Shield, Building 등 IDamageable 구현만 하면 자동 지원
효과:
실무:
인터페이스로 확장 지점을 만듭니다.
정의:
부모 타입을 자식 타입으로 바꿀 수 있어야 함
방향:
부모 → 자식 교체 가능
예시:
IDamageable 타입 변수에 TankHealth, Shield, Building 모두 할당 가능
target.TakeDamage(10) 모두 동작
효과:
실무:
인터페이스 구현체는 언제든 교체 가능해야 합니다.
정의:
인터페이스를 작게 분리
의미:
필요 없는 메서드 구현 강제 금지
예시:
IDamageable - TakeDamage만
IHealable - Heal만
각각 필요한 것만 구현
반례:
큰 인터페이스 IEntity에 TakeDamage, Heal, Stun 모두 있으면
건물은 Heal 필요 없는데 강제 구현
실무:
인터페이스는 1-3개 메서드만
정의:
구체가 아닌 추상에 의존
의미:
구체 클래스 대신 인터페이스 참조
예시:
TankHealth 대신 IDamageable 타입으로 참조
효과:
실무:
TryGetComponent<인터페이스> 패턴 사용
이유:
매 프레임 검색 → 성능 낭비
문제:
60fps면 초당 60번 검색
해결:
Awake/Start에서 캐싱 후 재사용
실무:
Awake/Start에서 캐싱 필수
1. Update에서 GetComponent 금지
Awake에서 캐싱
2. God Component 방지
100줄 넘으면 분리, 1컴포넌트 = 1책임
3. 순환 참조 방지
A ↔ B 금지, 이벤트/인터페이스로 절단
4. RequireComponent 활용
필수 의존성 명시
실무:
이 4가지만 지켜도 80% 깔끔
1. 참조 캐싱
Awake에서 GetComponent 1회만
2. Update 최소화
이벤트/코루틴으로 대체, 매 프레임 계산 피하기
3. 오브젝트 풀링
총알/이펙트는 생성/파괴 대신 재사용
4. FixedUpdate 사용
Rigidbody 물리 처리는 FixedUpdate
실무:
캐싱 + 풀링이 가장 효과 큼
기준:
수천 개 이상 오브젝트에서 성능 병목
컴포넌트 패턴:
ECS (DOTS):
권장:
대부분 게임은 컴포넌트 패턴으로 충분
병목 보이는 핵심 루프만 ECS 혼용
실무:
먼저 컴포넌트로 만들고, 필요시 ECS 전환
1. 컴포넌트 (90%)
Unity 기본 구조
2. 오브젝트 풀링 (80%)
메모리 관리 필수
3. 싱글톤 (70%)
전역 접근 (남용 주의)
4. 옵저버/이벤트 (65%)
통신
5. 스테이트 FSM (60%)
AI, 캐릭터 상태
참고:
GoF 23개 중 실제로는 7~8개만 씀
문제:
매 프레임 검색 → 성능 낭비
개선:
Awake에서 캐싱 후 Update에서 재사용
문제:
개선:
MoveComponent, CombatComponent, JumpComponent, HealthComponent, InventoryComponent, SaveComponent, UIComponent로 분리
문제:
A → B, B → A
둘 다 독립 사용 불가
개선 1: 이벤트
A는 이벤트 발행만, B는 구독만
개선 2: 단방향
A → B (B만 A를 앎)
문제:
구체 타입에 의존 → 확장 어려움
개선:
인터페이스 의존으로 변경
IDamageable 사용하면 Shield, Building 등 자동 지원
문제:
직접 참조 → 높은 결합도
개선:
이벤트 사용
Health는 OnHealthChanged 발행만
UIManager는 구독해서 처리
25문제 중:
각 답변마다 포함해야 할 것:
작성일: 2025-10-14
난이도: 미들 레벨
목표: 컴포넌트 패턴 마스터