Awake
OnEnable
Start
Update
FixedUpdate
LateUpdate
OnApplicationQuit
OnDisable
OnDestroy
MonoBehaviour 클래스에서 Start와 Awake의 차이점은 무엇이며, 이를 적절히 사용하는 방법에 대해 설명해주세요.
왜 MonoBehaviour가 필요할까?
주요 메서드
Awake
: 초기화 로직을 배치하며, 종속성 설정 등에 적합Start
: 초기화 후 게임 시작 시 실행Update
: 프레임 기반 작업에 사용FixedUpdate
: 물리 연산 업데이트에 사용LateUpdate
: Update가 끝난 뒤 호출OnEnable/OnDisable
: 오브젝트 활성화/비활성화 시 동작OnDestroy
: 오브젝트가 파괴되기 전에 실행Start와 Awake의 차이점
Awake
Start
Update
FixedUpdate
프레임이 아니라 고정된 시간 간격으로 호출되며, 주로 물리 연산에 사용
이 고정 시간 간격은 프로세서 성능과 관계없이 일정하게 유지되도록 설계되었습니다. 기본적으로 Unity의 Fixed Timestep 설정(기본값: 0.02초 = 50FPS)에 따라 호출됩니다.
고정 시간 간격 조정 가능
Unity의 Time.fixedDeltaTime 값을 변경하면 FixedUpdate 호출 간격이 달라집니다. (예: 물리 시뮬레이션을 더 정밀하게 처리하고 싶을 때 고정 시간 간격을 줄일 수 있음)
성능이 부족할 때의 영향
CPU나 GPU 성능이 낮아 게임이 느려지더라도, FixedUpdate의 호출 횟수는 고정 간격을 유지하기 위해 한 프레임 내에서 여러 번 호출될 수 있습니다. 반대로 성능이 매우 높은 경우, FixedUpdate 호출 간의 시간 간격이 더 길어질 수 있습니다.
정확히 일정하지 않을 수 있는 경우
이론적으로는 일정해야 하지만, 프레임 드랍이나 지나치게 높은 물리 연산 부하가 걸리면 Unity는 물리 연산과 FixedUpdate의 일정을 맞추기 위해 스킵하거나 여러 번 호출하기도 합니다.
FixedUpdate는 컴퓨터 성능과는 무관하게 일정한 주기를 유지하려고 노력하지만, 극단적인 상황에서는 영향을 받을 수도 있음
예: Rigidbody의 움직임 계산.
LateUpdate
Time.deltaTime
은 현재 프레임과 이전 프레임 사이의 시간 간격(초)을 나타냄yield
코루틴은 모든 Update 함수가 다음 프레임에 호출된 후 계속됩니다.yield WaitForSeconds
지정한 시간이 지난 후, 모든 Update 함수가 프레임에 호출된 후 계속됩니다.yield WaitForFixedUpdate
모든 FixedUpdate가 모든 스크립트에 호출된 후 계속됩니다.yield WWW WWW
다운로드가 완료된 후 계속됩니다.yield StartCoroutine
코루틴을 연결하고 MyFunc 코루틴이 먼저 완료되기를 기다립니다.Invoke
: 특정 메서드를 일정 시간 후에 한 번 호출코루틴
: 복잡한 시간 제어나 반복 동작을 구현할 수 있음코루틴
멀티쓰레딩
최적화 방법
오브젝트 풀링
: 자주 생성/삭제되는 오브젝트를 미리 만들어 재사용.Draw Call 감소
: Material과 Mesh 병합을 통해 배치 수 줄이기.LOD (Level of Detail)
: 카메라 거리 기반으로 저해상도 메쉬 렌더링.Occlusion Culling
: 보이지 않는 오브젝트의 렌더링 생략.텍스처 압축
: 텍스처 포맷을 효율적으로 설정.최적화에서 중요한 부분
텍스처 포맷 예시
ETC2, ASTC
: 모바일 최적화.Find
함수는 이름 기반으로 오브젝트를 검색하기 때문에 속도가 느리고, 실시간 성능에 영향을 미칠 수 있습니다.LinkedList는 노드(Node)라는 개별 요소들이 서로 연결된 구조로, 각 노드는 데이터와 다음 노드를 가리키는 주소를 포함합니다.
LinkedList는 언제 사용하면 좋은 자료구조인가요?
동적 데이터 관리가 필요한 경우
: 크기를 미리 지정할 필요 없이 데이터를 동적으로 추가/삭제할 수 있습니다.삽입/삭제가 빈번한 경우
: 중간에 데이터를 삽입하거나 삭제하는 작업이 빈번하면 Array와 달리 데이터 이동이 필요 없으므로 효율적입니다.메모리 효율적인 활용
: 배열과 달리 메모리를 선형적으로 할당하지 않아도 되므로, 불규칙적인 데이터 크기와 위치를 처리하기 좋습니다.LinkedList는 언제 사용하기 불리한가요?
랜덤 접근이 필요한 경우
: 배열처럼 인덱스를 통한 직접 접근이 불가능하며, 원하는 데이터를 찾기 위해 처음부터 순차적으로 검색해야 하므로 시간이 더 걸립니다.오버헤드 증가
: 각 노드마다 포인터를 저장하므로, 메모리 사용량이 배열보다 큽니다.캐시 성능 저하
: 배열은 메모리에 연속적으로 저장되어 캐시 효율이 좋지만, LinkedList는 그렇지 못해 성능이 떨어질 수 있습니다.LinkedList를 본인의 프로젝트에 적용해본 경험
LinkedList를 사용했던 프로젝트는 간단한 히스토리 관리 시스템 개발에서였습니다. 사용자가 입력한 명령을 저장하고 "뒤로가기"나 "앞으로 가기" 같은 기능을 제공하기 위해 이중 연결 리스트(Doubly Linked List)를 사용했습니다. 이를 통해 현재 상태를 기준으로 이전 상태로 이동하거나 이후 상태로 빠르게 이동할 수 있었으며, 명령 삽입과 삭제가 유연하게 이루어졌습니다.
LIFO(Last In, First Out) 구조, 가장 나중에 들어온 데이터가 가장 먼저 나가는 방식으로 동작합니다.
Stack은 언제 사용하면 좋은 자료구조인가요?
재귀적인 문제 처리
: 함수 호출 스택처럼, 재귀를 구현하거나 트리/그래프의 깊이 우선 탐색(DFS)을 할 때 유용합니다.작업 순서 제어
: 연산자 우선순위 계산, 수식 괄호 검사, 문자열 뒤집기와 같은 작업에서 유리합니다.히스토리 관리
: 웹 브라우저의 뒤로가기/앞으로 가기 기능, UNDO/REDO 기능 구현에 적합합니다.Stack은 언제 사용하기 불리한가요?
순차적 접근이 필요한 경우
: Stack은 맨 위의 요소만 접근 가능하므로, 특정 인덱스에 직접 접근해야 하는 경우 부적합 합니다.크기 제한이 명확하지 않을 때
: 메모리가 제한된 환경에서 크기가 동적으로 계속 증가할 가능성이 있으면 위험할 수 있습니다.Stack을 본인의 프로젝트에 적용해본 경험
Stack은 HTML 태그 유효성 검사기를 구현할 때 활용했습니다. 열리는 태그와 닫히는 태그의 쌍을 확인하기 위해, 열린 태그를 Stack에 저장하고 닫히는 태그가 나타날 때 매칭 여부를 확인했습니다. 잘못된 순서나 비매칭 태그를 발견할 경우 오류를 반환하도록 설계하여 문서의 구조적 무결성을 검사하는 기능을 성공적으로 구현했습니다.
FIFO(First In, First Out) 구조, 가장 먼저 들어온 데이터가 가장 먼저 나가는 방식으로 동작합니다.
Queue는 언제 사용하면 좋은 자료구조인가요?
순서가 중요한 경우
: 작업 요청이 들어온 순서대로 처리해야 하는 경우(예: 프린터 작업, 콜센터 대기열 등).데이터 스트리밍
: 실시간 데이터를 순차적으로 처리해야 하는 상황(예: 데이터 패킷 전송, 멀티스레드 작업의 작업 큐).폭넓은 배치 작업
: 너비 우선 탐색(BFS) 같은 알고리즘에서 사용됩니다.Queue는 언제 사용하기 불리한가요?
랜덤 접근이 필요한 경우
: Queue는 특정 인덱스의 요소에 직접 접근할 수 없으므로, 배열이나 LinkedList보다 비효율적입니다.많은 요소 삭제가 필요한 경우
: 삭제 시 요소 이동이 필요할 수 있어 부적합할 수 있습니다(일반 배열 기반 Queue의 경우).Queue를 본인의 프로젝트에 적용해본 경험
Queue를 활용한 프로젝트는 멀티스레드 환경에서의 작업 분배 시스템이었습니다. 여러 작업 요청이 동시에 들어오는 상황에서 작업 요청을 순차적으로 처리하기 위해 Queue를 사용했습니다. 작업이 요청되면 우선 작업 대기열에 추가되며, 별도의 작업 스레드가 대기열에서 작업을 하나씩 가져가 처리하도록 설계했습니다. 이를 통해 작업 처리의 안정성과 효율성을 높일 수 있었습니다.