일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- more effective c++
- 루아
- 암시적 변환
- 참조자
- c++
- operator new
- reference
- 예외
- 영화 리뷰
- Effective c++
- 비교 함수 객체
- virtual function
- 언리얼
- UE4
- resource management class
- lua
- implicit conversion
- 게임
- exception
- 반복자
- 영화
- effective stl
- 다형성
- 상속
- Smart Pointer
- 스마트 포인터
- 메타테이블
- 오블완
- 함수 객체
- 티스토리챌린지
- Today
- Total
스토리텔링 개발자
[UE4] 에셋 강참조 / 약참조 본문
개요
언리얼에서 에셋을 참조하는 방법은 두 가지가 있습니다.
참조하는 방법이라고 하니까 딱딱한 감이 없잖아 있는데요.
쉽게 말해서 액터가 특정 에셋을 가지고 있는 상황입니다.
근데 가지고 있으면 가지고 있는거지 강참조, 약참조라니요.
대체 무슨 차이일까요.
일반적인 참조(강참조)
우선 일반적인 경우를 살펴보도록 하겠습니다.
보통 에셋을 참조, 즉 소유하기 위해서는 보통 이렇게 하겠죠.
1. UPROPERTY() 멤버변수로 선언합니다.
2-1. C++에서 LoadObject 함수를 사용하여 직접 에셋을 불러와 사용하거나
2-2. 엔진에서 에셋을 직접 선택하여 사용합니다.
이런 일반적인 방식이 바로 강참조입니다.
즉 에셋을 지정하는 시점에 에셋이 메모리에 올라가는 방식을 강참조라고 합니다.
일반적인 참조의 문제점
당연히 잘 동작합니다.
일반적인 경우 문제도 없습니다.
하지만 이런 경우엔 조금 곤란해질 수 있습니다.
바로 강참조를 가진 오브젝트를 다른 오브젝트가 또 강참조하는 경우 입니다.
아래 그림을 함께 보실까요.
오브젝트 B가 A를 강참조하고 있습니다.
이 오브젝트 B를 로드를 하는 시점에는 이런 일이 발생합니다.
1. 오브젝트 B를 로드하기 위해 내부의 것을 함께 로드, 메모리에 올리기 시작합니다.
2. 멤버 변수인 오브젝트 A를 로드합니다.
3. 오브젝트 A를 로드하기 위해 내부의 것을 함께 로드합니다.
4. 멤버 변수인 강참조 오브젝트를 로드합니다.
5. 강참조 오브젝트를 로드하기 위해 내부의 것을 함께 로드합니다.
6. 강참조 오브젝트 내부에 또 다른 강참조 에셋이 있으면 위와 같은 과정을 반복합니다....
아직 사용도 하지 않았는데 메모리엔 오브젝트 A, 그리고 그 내부 에셋들이 모두 올라가 버렸습니다.
즉 강참조는 중첩으로 인해 사용하지도 않을 에셋들을 미리 마구 메모리에 얹어버릴 수 있습니다.
지금은 단순한 중첩이지만, 이런 중첩이 몇 번만 더 쌓여도 오브젝트 하나를 로드했을 뿐인데 메모리 점유량은 기하급수적으로 올라갈 수도 있을테지요.
FSoftObjectPath / TSoftObjectPtr(약참조)
강참조는 참조 시점에 메모리에 올라가는 에셋이 문제였습니다.
그렇다면 이들이 참조 시점에 로드되지 않도록 처리하면 되지 않을까요?
그 아이디어를 구현한 것이 바로 약참조, FSoftObjectPath 혹은 TSoftObjectPtr 입니다.
이들은 에셋은 참조 시점에 메모리에 로드되지 않습니다.
오브젝트의 전체 이름(경로)으로 된 스트링을 참조할 뿐입니다.
에셋 전체 vs 오브젝트의 경로.
메모리에 올라가는 용량에서 엄청난 차이가 있겠죠?
언급했듯 FSoftObjectPath나 TSoftObjectPtr는 단지 경로일 뿐입니다.
하지만 에디터에서는 이들을 UObject 포인터인 것처럼 처리해 줍니다.
즉 사용자 입장에서는 별반 차이 없이 에셋을 지정할 수 있습니다.
아래처럼 말이죠.
FSoftObjectPath와 TSoftObjectPtr의 차이점
그렇다면 이 두 가지는 무슨 차이가 있을까요?
실은 본질적으로는 동일합니다.
TSoftObjectPtr는 내부적으로 FSoftObjectPath를 가지고 있습니다.
주요 차이점을 알아보도록 하겠습니다.
1.
TSoftObjectPtr는 탬플릿이고, 지정한 클래스의 하위 타입만 지정할 수 있도록 제한할 수 있습니다.
FSoftObjectPath는 제약 없이 경로를 소유할 수 있죠.
2.
TSoftObjectPtr는 생성된 오브젝트를 -> 연산자를 통해 접근할 수 있습니다.(이름처럼 포인터처럼 동작합니다.)
FSoftObjectPath는 오브젝트 생성을 요청하면 오브젝트를 내뱉습니다. 생성된 오브젝트는 따로 관리해 주어야 합니다.
즉, TSoftObjectPtr은 포인터 역할을 대리합니다. 예컨대 공유 포인터와 비슷한 방식으로요.
아. 당연히 경로일 뿐이니까 각 에셋들은 사용 직전에 로드를 해줘야 합니다.
TSoftObjectPtr는 LoadSynchronous
FSoftObjectPath는 TryLoad
함수를 사용합니다.
'개발 > 언리얼 엔진' 카테고리의 다른 글
[UE4] 스마트 포인터(Smart Pointer) (0) | 2021.08.09 |
---|---|
[UE4] 동기 / 비동기 에셋 로딩 (0) | 2021.07.15 |
[UE4] 컴포넌트(Component) (0) | 2021.07.01 |
[UE4] 콜리전(Collision) (0) | 2021.06.24 |
[UE4] 트레이스(Trace) (0) | 2021.06.22 |