Editor vs Runtime GC
PIE νΉμμ±, Editor Only κ°μ²΄, μλν° λ©λͺ¨λ¦¬ κ΄λ¦¬μ GC μ°¨μ΄λ₯Ό μ΄ν΄ν©λλ€
μλν°μ λ°νμ GC μ°¨μ΄
μλν° νκ²½μμμ GC λμ νΉμ±
μ£Όμ μ°¨μ΄μ
| νλͺ© | μλν° | λ°νμ (Shipping) |
|---|---|---|
| MaxObjects | 12,582,912 | 2,162,688 |
| TObjectPtr λμ | μ§μ° λ‘λ© + μ κ·Ό μΆμ | raw ν¬μΈν°μ λμΌ |
| UObject μ | λ§€μ° λ§μ (μμ λ©νλ°μ΄ν°) | μλμ μΌλ‘ μ μ |
| GC λΉλ | μ¬μ©μ λμμ μμ‘΄ | gc.TimeBetween... κΈ°λ° |
| Undo/Redo μν₯ | νΈλμμ κ°μ²΄ λ³΄κ΄ | μμ |
| RF_Standalone | μμ 보νΈμ μ¬μ© | κ±°μ μ¬μ© μ ν¨ |
μλν°λ λͺ¨λ μμ μ λ©νλ°μ΄ν°, μΈλ€μΌ, μλν° μ μ© νλ‘νΌν°λ₯Ό λ©λͺ¨λ¦¬μ μ μ§ν©λλ€. λν Undo/Redoλ₯Ό μν νΈλμμ νμ€ν 리λ GC Rootμ μ°κ²°λμ΄ λ©λͺ¨λ¦¬λ₯Ό μ°¨μ§ν©λλ€. μλν°μμμ λ©λͺ¨λ¦¬ μ¬μ©λμ λ°νμμ 3~5λ°°κ° λ μ μμ΅λλ€.
PIE(Play In Editor) GC νΉμμ±
PIE λͺ¨λμμμ GC μ£Όμμ¬ν
PIEμ μλν° κ³΅μ‘΄
// PIEμμ GCκ° λ€λ₯΄κ² λμνλ μ :
1. μλ λΆλ¦¬
μλν° μλμ PIE μλκ° λμ μ‘΄μ¬
κ° μλμ κ°μ²΄λ λ
립μ μΌλ‘ GC λμ
2. PIE μ’
λ£ μ GC
PIE μ’
λ£ β κ²μ μλμ λͺ¨λ κ°μ²΄ νκ΄΄
λλ GC λ°μ β μλν° μ μ λ©μΆ€
3. PIEμμ Standaloneκ³Ό λ€λ₯Έ λμ
// PIEμμλ§ λ°μνλ λ¬Έμ :
// - μλν° μμ
μ μ§μ μ°Έμ‘°νλ©΄ PIE μ’
λ£ νμλ λ¨μ
// - NonPIEDuplicateTransientλ‘ μ μ΄
// PIE κ°μ§
if (GEngine->IsEditor())
{
if (GWorld->IsPlayInEditor())
{
// PIE νκ²½
}
}
// PIEμμ μμ
볡μ μ¬λΆ νμΈ
UPROPERTY(NonPIEDuplicateTransient)
UObject* EditorOnlyRef;
// PIE μμ μ μ΄ νλ‘νΌν°λ 볡μ λ¨
// Standalone κ²μμμλ 볡μ μ λ¨
Editor Only κ°μ²΄μ μΏ νΉ
#if WITH_EDITORμ μλν° μ μ© UObject κ΄λ¦¬
μλν° μ μ© κ°μ²΄μ GC
UCLASS()
class UMyData : public UObject
{
GENERATED_BODY()
// μλν°μμλ§ μ‘΄μ¬νλ νλ‘νΌν°
#if WITH_EDITORONLY_DATA
UPROPERTY(EditAnywhere)
UTexture2D* EditorPreviewTexture;
// μΏ νΉ μ μ κ±°λ¨ β λ°νμ GC λΆν μμ
UPROPERTY(EditAnywhere)
FString DeveloperNotes;
#endif
// λ°νμμλ μ‘΄μ¬νλ νλ‘νΌν°
UPROPERTY()
UStaticMesh* GameMesh;
};
// μλν° μ μ© λͺ¨λμ UObject
// UEditorUtilityWidget, UEditorUtilityObject λ±μ
// μΏ νΉ μ μμ ν μ κ±°λμ΄ λ°νμμ μν₯ μμ
WITH_EDITORONLY_DATA λΈλ‘ λ΄μ UPROPERTYλ μΏ νΉ(ν¨ν€μ§) μ μμ ν μ κ±°λ©λλ€. μ΄λ ν΄λΉ νλ‘νΌν°κ° GC ν ν° μ€νΈλ¦Όμλ ν¬ν¨λμ§ μμ λ°νμ GC μ±λ₯μ μν₯μ μ£Όμ§ μμ΅λλ€. μλν° μ μ© λ°μ΄ν°λ μ΄ λΈλ‘ μμ λ£μΌμΈμ.
μλν° λ©λͺ¨λ¦¬ κ΄λ¦¬ ν
λκ·λͺ¨ νλ‘μ νΈμμ μλν° λ©λͺ¨λ¦¬ λ¬Έμ ν΄κ²°
μλν° λ©λͺ¨λ¦¬ μ μ½ μ λ΅
// 1. μμ
λ μ§μ€νΈλ¦¬ μΊμ κ΄λ¦¬
// μ½ν
μΈ λΈλΌμ°μ μ λͺ¨λ μμ
= λ©νλ°μ΄ν° λ‘λ
// ν΄λ νν°λ₯Ό νμ©νμ¬ νμν μμ
λ§ νμ
// 2. μλν°μμ κ°μ GC
// νμΌ λ©λ΄ β "Collect Garbage"
// λλ μ½μ: obj gc
// 3. μ°Έμ‘° μ 리
// μ½ν
μΈ λΈλΌμ°μ β μμ
μ°ν΄λ¦ β "Fix Up Redirectors"
// 리λλ ν°κ° μμ
μ GCλ‘λΆν° 보νΈνλ κ²½μ° μμ
// 4. μλν° GC μ€μ μ‘°μ
gc.MaxObjectsInEditor=16777216 // λ λ§μ κ°μ²΄ νμ©
// 5. μλν° μ μ© μμ
μ΅μν
// Developer ν΄λλ μΏ νΉ μ μ μΈλ¨
// ν
μ€νΈ μμ
μ Developer ν΄λμ λ°°μΉ
ν΅μ¬ μμ½
- μλν°λ λ°νμλ³΄λ€ UObject μκ° ν¨μ¬ λ§κ³ MaxObjects νκ³λ λμ΅λλ€
- PIE μ’ λ£ μ λλ GCκ° λ°μνλ©°, μλν° μμ μ§μ μ°Έμ‘°λ λ©λͺ¨λ¦¬ λμλ₯Ό μ λ°ν©λλ€
- WITH_EDITORONLY_DATAμ νλ‘νΌν°λ μΏ νΉ μ GC ν ν° μ€νΈλ¦Όμμ μμ ν μ κ±°λ©λλ€
- TObjectPtrλ μλν°μμ μ§μ° λ‘λ©μ, λ°νμμμλ raw ν¬μΈν° μ±λ₯μ μ 곡ν©λλ€
- ν μ€νΈ μμ μ Developer ν΄λμ λ°°μΉνμ¬ μΏ νΉ μ μ μΈν©λλ€
λμ κ³Όμ
λ°°μ΄ λ΄μ©μ μ§μ μ€μ΅ν΄λ³΄μΈμ
μλν° PIE(Play In Editor)μ Standalone λΉλμμ λμΌν GC ν μ€νΈ μ½λλ₯Ό μ€ννμΈμ. gc.TimeBetweenPurgingPendingKillObjects, μλν° μ μ© Root κ°μ²΄, RF_Standalone νλκ·Έ λ±μ μ°¨μ΄λ₯Ό νλ‘ μ 리νμΈμ.
#if WITH_EDITOR λΈλ‘μμ GEditor->GetTransaction()μ μ¬μ©νμ¬ Undo νμ€ν λ¦¬κ° GCμ λ―ΈμΉλ μν₯μ λΆμνμΈμ. λλμ μλν° μμ ν Undo νμ€ν 리μ λ©λͺ¨λ¦¬ μ¬μ©λμ memreportλ‘ νμΈνμΈμ.
μλν°μμ μμ μ GC νμΉλ₯Ό μ€μ΄κΈ° μν μλν° μ νΈλ¦¬ν° νλ¬κ·ΈμΈμ κ°λ°νμΈμ. μλν° μ ν΄ μκ°μ GCλ₯Ό μ€ννλ μ€μΌμ€λ¬, μλν° μ μ© λ©λͺ¨λ¦¬ 리ν¬νΈ, Undo νμ€ν 리 μ 리 κΈ°λ₯μ ν¬ν¨νμΈμ.