Unity의 생명주기 메서드 중 Awake(), Start(), Update()의 차이점
Awake()
- 게임 오브젝트가 초기화될 때 호출됩니다.
- 스크립트 인스턴스가 로딩될 때 한 번만 호출됩니다.
- 모든 객체가
Awake()
를 호출한 후에만 Start()
가 호출됩니다.
-
Awake()
는 게임 오브젝트가 비활성 상태여도 호출됩니다.
- 주로 변수나 참조의 초기화에 사용됩니다.
Start()
-
Awake()
다음에 호출되며, 첫 프레임 업데이트 전에 한 번만 호출됩니다.
- 게임 오브젝트가 활성 상태인 경우에만 호출됩니다.
- 다른 모든 스크립트의
Awake()
가 호출된 후에 호출되므로, 다른 컴포넌트나 게임 오브젝트에 대한 참조를 안전하게 설정하는 데 사용될 수 있습니다.
Update()
- 매 프레임마다 호출됩니다.
- 주로 프레임마다 수행되어야 하는 연산, 입력 처리, 시뮬레이션 등에 사용됩니다.
- 프레임 속도에 따라 호출 빈도가 변할 수 있으므로, 시간에 의존하는 연산을 수행할 때
Time.deltaTime
과 같은 값을 사용하여 보정해야 합니다.
Prefab
- Unity의 “Prefab”은 “Prefabricated Object”의 줄임말로, 게임 개발에서 중요한 요소 중 하나
- Prefab은 게임 오브젝트와 해당 오브젝트의 모든 컴포넌트, 속성, 자식 오브젝트를 포함한 전체 구조를
저장하는 템플릿 또는 청사진과 같은 것
Prefab의 주요 특징 및 용도:
재사용성
- 한 번 생성된 Prefab은 여러 장면이나 다른 Prefab 내에서 여러 번 사용할 수 있음
- 게임 내에서 반복적으로 등장하는 적 캐릭터나 아이템을 Prefab으로 만들면, 필요할 때마다 쉽게 재사용 가능
일관성
- Prefab의 인스턴스를 수정하면, 해당 변경 사항은 모든 인스턴스에 반영
- 이를 통해 게임 전체에서 일관된 오브젝트를 유지
효율성
- 복잡한 게임 오브젝트와 그 구성 요소를 미리 만들어 두고, 런타임 중에 빠르게 생성하거나 복제
변형
- Prefab 인스턴스는 원래의 Prefab과 독립적으로 수정할 수 있음
- 필요한 경우 특정 인스턴스에만 변경 사항을 적용하거나, 변경 사항을 원래의 Prefab에 적용하여 모든
인스턴스를 업데이트할 수 있음
Unity에서 메모리 누수를 방지하기 위한 best practice
오브젝트 제거
-
Destroy()
함수를 사용하여 더 이상 필요하지 않은 게임 오브젝트를 제거
-
Object.Destroy()
를 사용하여 불필요한 Asset 오브젝트를 제거
이벤트 및 델리게이트 해제
- 오브젝트가 파괴되기 전에 이벤트 리스너나 델리게이트에서 해당 오브젝트를 제거
정적 변수 주의
- 정적 변수는 앱의 생명주기 동안 계속 메모리에 남아 있습니다. 필요에 따라 적절히 초기화하거나 제거
코루틴 관리
-
StopCoroutine()
을 사용하여 더 이상 필요하지 않은 코루틴을 중지
풀링 사용
- 빈번한 오브젝트 생성과 제거는 가비지 컬렉션을 일으킬 수 있음
- 오브젝트 풀링을 사용하여 미리 오브젝트를 생성하고 재사용합니다.
Unmanaged 리소스 관리
-
System.IDisposable
인터페이스를 구현한 클래스의 인스턴스를 사용한 후 Dispose()
메서드를 호출하여 리소스를 제거
텍스처 및 메터리얼 관리
- 더 이상 사용되지 않는 텍스처나 메터리얼은
Resources.UnloadUnusedAssets()
를 사용하여 제거
씬 전환
- 씬을 전환할 때
SceneManager.LoadScene()
의 두 번째 매개변수로 LoadSceneMode.Single
을 사용하여 이전 씬의 모든 오브젝트를 제거
프로파일링
- Unity의 메모리 프로파일러를 사용하여 메모리 사용량을 모니터링하고 누수 원인을 찾기
코드 리뷰
- 정기적으로 코드 리뷰를 진행하여 메모리 누수가 발생할 가능성이 있는 코드를 식별하고 수정
Coroutines
- Unity의 Coroutines는 특별한 종류의 메서드로, 일반 메서드와는 달리 여러 프레임에 걸쳐 실행 됨
- Coroutines는
IEnumerator
를 반환하는 메서드로 정의되며, yield return
문을 사용하여 실행을 일시 중단하고 특정 조건이나 시간이 지난 후에 다시 재개할 수 있음
Coroutines의 주요 특징
- 비동기 처리 : Coroutines를 사용하면 복잡한 연산, 애니메이션, 타이머 등을 비동기적으로 처리
- 코드 간결성 : 일련의 동작을 시간에 따라 나열하여 쓰기 때문에 코드가 읽기 쉽고 이해하기 쉬움
- 유연성 :
yield return
을 사용하여 특정 조건이 충족될 때까지 실행을 중단하거나 특정 시간 동안 대기할 수 있음
Unity Render Pipeline
- Unity의 렌더링 파이프라인은 3D 콘텐츠를 화면에 그리는 데 사용되는 일련의 과정
- Unity는 다양한 유형의 렌더링 파이프라인을 제공하며, 각각은 특정 유형의 프로젝트와 장치에 최적화
- Unity 2018부터 Unity는 세 가지 주요 렌더링 파이프라인을 제공
- Built-in (전통적인)
- Universal Render Pipeline (URP)
- High Definition Render Pipeline (HDRP).
Built-in Render Pipeline (전통적인 렌더링 파이프라인)
- 이전 버전의 Unity에서 주로 사용되던 기본 파이프라인입니다.
- 대부분의 장치와 호환되며, 범용적인 사용 사례에 적합합니다.
Universal Render Pipeline (URP)
- 이전의 Lightweight Render Pipeline (LWRP)을 기반으로 합니다.
- 다양한 플랫폼에 걸쳐 일관된 렌더링 품질을 제공하도록 설계되었습니다.
- 모바일, VR, 데스크톱 등 다양한 플랫폼에 적합하며, 중간 품질의 그래픽을 제공합니다.
High Definition Render Pipeline (HDRP)
- 고해상도 및 고품질의 그래픽을 제공하기 위한 파이프라인입니다.
- 현실적인 시각 효과와 물리 기반의 렌더링을 위해 최적화되어 있습니다.
- 주로 고사양 PC, 콘솔 및 최신 VR 장치에 적합합니다.
렌더링 파이프라인의 주요 단계 (기본적인 개요)
-
Culling:
- 화면에 그려지지 않는 오브젝트 (카메라 시야 밖, 오클루전에 의해 가려진 오브젝트 등)를 식별하고 제거하는 과정
-
Rendering:
- 실제로 화면에 그려질 오브젝트의 렌더링을 수행
- 이 단계는 여러 하위 단계로 나뉘며, 각 오브젝트의 셰이더와 물리 기반의 렌더링 설정에 따라 처리
-
Post-processing:
- 최종 렌더링된 이미지에 추가적인 효과 (블루, 컬러 그레이딩, 블러 등)를 적용하는 과정
-
Output:
Global Illumination
- Global Illumination (GI)는 컴퓨터 그래픽스에서 실제 세계의 빛 전파를 모방하는 방법
- 빛이 환경의 각 객체에 반사, 흡수, 투과하는 방식을 시뮬레이션
- GI는 장면 내의 모든 빛원에서 발생하는 간접 빛을 계산하여, 그림자, 반사, 간접 빛 등의 복잡한 빛 효과를 생성
원리
Direct Lighting
- 빛원에서 바로 오브젝트로 가는 빛
- 기본적인 렌더링에서 주로 계산되는 빛
Indirect Lighting
- 빛원에서 다른 오브젝트나 표면에 반사되거나 투과한 후 대상 오브젝트에 도달하는 빛
- GI는 이러한 간접 빛의 계산에 중점을 둠
주요 GI 계산방식
Realtime GI
- 실시간으로 간접 빛을 계산
- 이 방식은 동적인 객체나 빛원에 잘 맞으며, 게임 내에서 환경이나 빛의 상태가 자주 변경되는 경우 유용
Baked GI
- 미리 계산된 간접 빛 정보를 텍스처로 저장
- 이 방식은 정적인 환경에 적합하며, 런타임 성능에 크게 영향을 주지 않음
중요성
현실감
- GI는 실제 세계의 빛 전파를 흉내내므로, 장면이 훨씬 더 현실적으로 보임
- 간접 빛, 색상 반사, 빛이 투과하는 효과 등은 실제 세계의 빛 효과와 매우 유사
통합된 렌더링
- GI를 사용하면 다양한 렌더링 요소가 통합적으로 처리됨
- 예를 들어, 반사된 빛의 색상이 다른 오브젝트에 영향을 미칠 수 있음
높은 품질
- GI는 그림자의 부드러움, 빛의 산란, 반사 등의 렌더링 품질을 크게 향상시킴
감각적 표현
- GI를 사용하여 일광, 실내 조명, 마술시간 등의 특정 빛 조건을 더 감각적으로 표현할 수 있음
Scriptable Objects
용도
- 게임 데이터 저장 : 무기, 캐릭터, 스킬, 퀘스트, 아이템 등의 게임 데이터를 저장하고 관리
- 게임 설정 : 게임 내의 다양한 설정 값을 저장하고 쉽게 수정할 수 있음
- 재사용 가능한 데이터 : 특정 씬 또는 게임 오브젝트와 연결되지 않고, 여러 곳에서 재사용할 수 있는 데이터를 저장
- 모듈화된 로직 : 특정 로직이나 기능을 Scriptable Object 내에서 관리하고, 다른 게임 오브젝트와 독립적으로 작동하게 만들 수 있음
장점
- 분리된 데이터 : Scriptable Objects를 사용하면 데이터와 로직을 분리하여, 데이터 관리가 더욱 쉬워짐
- 메모리 효율 : 여러 게임 오브젝트에서 동일한 데이터를 공유할 수 있기 때문에 메모리 사용량을 최적화
- 편리한 편집 : Unity 에디터 내에서 직접 Scriptable Objects를 수정하고 관리할 수 있어,
데이터의 시각적 편집이 용이
- 버전 관리 : Scriptable Objects는 일반적인 Unity 에셋처럼 디스크에 저장되기 때문에,
버전 관리 시스템 (예: git)과 함께 사용하기 쉬움
- 안정성 : 게임 실행 중에 실수로 데이터를 변경할 위험이 줄어듬, 런타임에 Scriptable Object의 데이터를 변경하지 않는 한, 원본 데이터는 수정되지 않음
Raycasting
- Raycasting은 컴퓨터 그래픽스와 게임 개발에서 주로 사용되는 기술
- 시작점과 방향을 가진 “레이” (선)을 투사하여 그 레이가 다른 객체와 어떻게 상호작용하는지 결정하는 과정
Raycasting의 원리
- 시작점과 방향 : Raycasting은 특정 시작점에서 주어진 방향으로 레이를 투사
- 충돌 감지 : 이 레이가 다른 객체와 부딪히면, 그 충돌 지점과 충돌한 객체에 대한 정보를 반환
- 거리 제한: 필요한 경우, 레이의 최대 투사 거리를 지정하여 그 범위 내에서만 충돌을 감지
게임 내에서의 활용
플레이어의 시야 감지
- 플레이어가 보고 있는 방향으로 레이를 투사하여, 플레이어가 어떤 객체를 바라보고 있는지 확인
- 예를 들어, FPS 게임에서 조준점이 어떤 적에게 가리키고 있는지 결정할 때 사용
AI 시야
- NPC나 적 AI가 플레이어나 다른 대상을 “보고” 있는지 확인하기 위해 Raycasting을 사용할 수 있음
프로젝타일 경로 예측
- 발사체가 어떤 경로로 날아갈지 예측하기 위해 레이를 사용할 수 있음
플레이어 이동
- 플레이어가 움직일 수 있는 표면 위를 클릭하거나 터치했을 때, 그 위치를 결정하기 위해 Raycasting을 사용
물리 기반 상호작용
- 레버, 버튼, 스위치 등과 같은 게임 내 객체와의 물리적 상호작용을 위해 Raycasting을 사용
지형 감지
- 캐릭터가 땅 위에 있는지, 어떤 경사도를 가진 지형 위에 있는지 등을 확인하기 위해 사용