레벨 디자인 & 배치 팁
- 4분할 뷰(Top/Front/Side/Persp)로 동시에 보며 배치하여 오차를 줄일 수 있다.
- Snapping(Grid/Angle)과 Location 이동 최소 단위를 설정해 딱 떨어지도록 배치가 가능하다.

빛이 누출되거나 콜리전 오차 발생을 예방할 수 있다.
라이트 및 Lumen
- 5가지 종류의 라이트: Directional Light / Point Light / Spot Light / Rect Light / Sky Light
| 라이트 | 핵심 속성 | 용도 |
| Directional | 무한 원거리 평행광, 방향만 고려 | 햇빛 표현 |
| Sky Light | 사방에서 들어오는 환경광 | 하늘/지평선 시뮬레이션 |
| Point | 한 점에서 방출 | 전구/횃불 등 간접조명 |
| Spot | 방향성 + 원뿔 각 | 연출용 스팟 |
| Rect | 면 전체 발광 | 면적광(넓고 균일) |
Trouble Shooting
- Skylight 값을 조정했는데 반영 되지 않는다면?
Skylight 조정했는데 반영 안 됨 → (Skylight → Details → Recapture)
- 어색한 빛(아티팩트) 빛이 발생하는 경우

1) 문제가 되는 material의 PDO(Pixel Depth Offset)을 끈다.
→ 왜? Lumen에서 PDO가 제대로 지원되지 않거나 원하는 그림자에 반영되지 않아 왜곡이 생길 수 있다.

2) Movable Directional Light 사용 시 천장 패널을 뚫는 것처럼 보일 수 있다. 메시 두께를 키우거나, 틈을 메우는 식으로 빛을 차단한다.
상속

→ 인스턴스에서 바꾼 값들을 “Apply Instance Changes to Blueprint”로 모든 인스턴스에 전파가 가능하다.
→ [BP_Torch_Dungeon “is-a” BP_Torch.]
콜리전과 캐릭터 설정
- 지금은 플레이 누르면 플레이어가 바닥을 뚫고 떨어진다.
→ 바닥 스태틱 메쉬의 콜리전이 없어서 그렇다.

우선, 바닥 SM을 찾아, collision을 추가하고, 아래와 같이 z extent를 10, z 성분 위치를 -10으로 해두며 바닥에 직접적이고 안정적으로 닿도록 설정해둔다.

1인칭 화면에서 팔을 숨겨보자, 그리고 움직이지 않는 경우
- 1인칭에서 사람의 팔이 보이지 않게 하고 싶다면?

→ BP_Player - First Person Mesh을 clear로 변경한다. 그리고 게임모드에서 Default Pawn 부분의 클래스를 내가 사용하는 BP_Player로 변경한다.
→ 이후 Play를 누르면, 플레이어가 움직이지 않는다.
그 이유는, 게임 모드에서 Player Controller Class가 내가 사용하는 BP_FirstPlayerController로 설정되어 있지 않아서, 컨트롤러가 Player(Pawn)을 소유하지 못해 입력이 캐릭터로 전달되지 않는다.
그래서 게임모드에서 Default Pawn 뿐만 아니라 Controller Class도 BP_FirstPlayerController로 변경해주었어야 했다.

즉, 입력이 안 된다 → GameMode에서 Default Pawn과 Player Controller Class 모두 확인한다(BP_Player / BP_FirstPlayerController).
Grabbable Object 세팅
플레이어에게 세팅한 Grabber을 통해, Grabbable Object를 잡아야 한다.
- Grabbable Object와 Grabber에 대한 설정

→ Grabber가 잡을 수 있는 오브젝트에게만 반응하도록 하기 위해, Player과 닿아도 반응하지 않도록 Ignore로 설정해둔다.
→ 그리고, 가고일 석상(Grabbable Object)의 Grabber Response를 Block으로 둔다. 이렇게 Grabber이 가고일 석상과 닿을 때, Block(충돌 감지)이 되어 Grabber가 오브젝트를 잡을 수 있다고 인식한다.
Grab/Attach 퍼즐 버그
“가고일 석상을 선반에 올리면, 올린 선반이 바닥으로 내려가며 문이 열리는 로직”에서, 아래와 같은 버그가 발생할 수 있다.
→ 선반에 올린 가고일 석상으로 인해, 문이 내려가다가 끼이는 문제가 발생할 수 있다. 가고일을 선반에 두었을 때 가고일이 고정되고, 물리 영향을 받지 않도록 하는 방법은 없을까?
→ 아래와 같은 방식으로 석상과 선반을 붙이면 된다.
// 선반에 고정하여 끼임을 방지한다.
if (AActor* A = HitActor){
if (auto* Prim = Cast<UPrimitiveComponent>(A->GetRootComponent())){
Prim->SetSimulatePhysics(false);
Prim->AttachToComponent(ShelfAnchor, FAttachmentTransformRules::KeepWorldTransform);
}
}
#include 부분에서 빨간 줄이 자꾸 생기는 경우
코드에는 문제가 없는데, visual studio에서 빨간 줄이 지속적으로 생기는 경우가 있다.
아래와 같은 방법으로 해결 가능(할 여지가 있다.)하다.
- 라이브 코딩에서 코드가 적용되지 않은 것으로 예측되는 경우, 언리얼 에디터를 닫고, 파일 탐색기에서 Intermediate, Binaries Folder를 삭제한 후, 프로젝트를 다시 실행한다. 이후에도 컴파일되지 않으면 프로젝트 소스 어딘가에 오류가 있을 가능성이 있다.
- Unreal에서 도구 → VS Code 프로젝트 새로 고침 → 한 파일이 추가 될 때마다 하는 것을 추천한다고 한다.
라이브 코딩/빌드/검색 이슈
라이브 코딩으로 블루 프린트에서 사용할 내용을 추가하였는데, 검색에 뜨지 않는 경우가 있다.
언리얼 에디터를 닫고, VSCode를 다시 열어 Ctrl+Shift+B를 눌러, 프로젝트를 Win64 ver으로 빌드(버전에 맞게)한다.
→ 근데, 터미널을 여는 방식에 따라 적용되지 않을 수 있는데, 그런 경우, default terminal을 powershell로 변경 후 적용한다.
+) 라이브 코딩 상의 대부분 버그는 라이브 코딩이 메모리 핫스왑이라는 것을 인지하지 못해 발생한다. 즉, 정식으로 빌드하고, 재실행하여 DLL 갱신이 필요하다.
BP에 존재하는 함수들이 깨져있다면?
- Binaries
C++ 클래스를 사용하는 경우 Binaries 폴더가 생기는데 이는 C++ 코드를 컴파일 시킨 결과들을 저장하게 된다. 제거해도 빌드할 때 마다 생성되니깐 컴파일 시 문제가 있다면 이 폴더를 삭제하고 다시 빌드하는 것도 방법이다.
- Intermediate
프로젝트에 필요한 임시 파일들을 저장한다. 이 폴더 또한 제거해도 프로젝트 파일을 우클릭해서 Generate Visual Studio project files를 통해 재생성할 수 있다.
- Saved
말 그대로 각종 세이브 파일들을 저장한다. Auto Save, screenshot 등이기에 제거해도 큰 무리가 없다고 한다.
즉, 언리얼 에디터를 닫고(IDE 말고) → 위 세 폴더를 지우고, → IDE에서 솔루션 빌드 후 → 빌드 완료되면, 언리얼 파일을 다시 실행시킨다.
(참고 블로그: https://haram17-devlog.tistory.com/30)
super?
부모 로직을 보존한 채 내 로직을 덧붙일 수 있다.
→ BeginPlay(), TickComponent() 등에서 Super::BeginPlay(); 호출을 통해, 상위 초기화/처리를 유지하도록 할 수 있다.
is-a와 has-a
is-a(상속): “BP_Torch_Dungeon” is‑a “BP_Torch.”
has-a(합성): “움직이는 벽” has-a “Mover”, 플레이어 has-a “Grabber”
포인터와 레퍼런스의 차이?
- 포인터:
→ nullptr로 초기화 가능하고, 나중에 다른 객체를 가리키게 할 수 있다.
→ 대신 nullptr인 상태에서 사용하면 크래시가 발생한다.
- 레퍼런스:
→ 무조건 어떤 객체를 참조해야 한다.
→ 한 번 연결하면 다른 걸 가리킬 수 없다.
→ 그래서 “필수로 존재해야 하는 객체”를 인자로 받을 때 사용하면 안전하다.
+) nullptr 여지가 있는 포인터를 쓸 땐 사용 직전 가드가 규칙이다(ex) if (!Ptr) return; 또는 if (IsValid(Obj)) {...} ).
ActorComponent, SceneComponent
둘 다 액터의 일부지만, SceneComponent는 공간 정보를 가진다는 게 큰 차이라고 볼 수 있다.
- ActorComponent
- 위치, 회전, 크기(Transform)가 없다.
- 게임 로직이나 데이터 관리용으로 사용한다.
- ex) Mover(움직임 계산), HealthComponent(체력 관리)
- SceneComponent
- 위치, 회전, 크기를 가진다.
- 월드 안에서 실제로 “어디에 있다”를 표현할 수 있다.
- ex) 카메라, Grabber, 라이트, 메시 등
헤더파일로의 컴파일 속도 개선
→ 불필요한 헤더 참조를 줄여 컴파일 속도를 개선할 수 있다.
ex) 나쁜 예시
// PlayerStateExt.h
#include "Weapon.h"
UCLASS() class APlayerStateExt : public APlayerState {
GENERATED_BODY()
UPROPERTY() AWeapon* CurrentWeapon;
};
// Weapon.h
#include "PlayerStateExt.h" // 서로 포함
UCLASS() class AWeapon : public AActor {
GENERATED_BODY()
UPROPERTY() APlayerStateExt* OwnerState;
};
ex) 좋은 예시
// PlayerStateExt.h
class AWeapon; // 전방 선언
UCLASS() class APlayerStateExt : public APlayerState {
GENERATED_BODY()
UPROPERTY() TObjectPtr<AWeapon> CurrentWeapon;
};
// Weapon.h
class APlayerStateExt; // 전방 선언
UCLASS() class AWeapon : public AActor {
GENERATED_BODY()
UPROPERTY() TObjectPtr<APlayerStateExt> OwnerState;
};
// 각 .cpp에서만 서로의 헤더 include
'공부 > Unreal' 카테고리의 다른 글
| [UE5] Obstacle Assault(언리얼 파이프라인, UPROPERTY, Live Coding, UE_LOG 등) (0) | 2025.09.18 |
|---|---|
| [UE5] Warehouse Wreckage (0) | 2025.07.09 |