프로그래밍/언리얼엔진

언리얼 공부 노트

하바사 2025. 2. 22. 23:44

1.무더기로 클래스들에 레퍼런스를 만드는 문제
- 레퍼런스를 GameInstance에서 싱글톤으로 관리할 것.

UGameInstance는 게임이 실행되는 동안 유지되는 글로벌 클래스로, 설정, 저장 데이터, 네트워크 상태 등을 관리하기에 용이.


2. VR과 같은 환경에서 그래픽스를 최적화를 위한 PostProcess 배제와 static lighting의 사용.

VR에서 Post Process와 실시간 라이팅 논란이 나오는 이유

(1) VR에서는 프레임율이 훨씬 더 중요함
일반 게임: 60FPS 정도면 충분

VR 게임: 최소 90FPS 이상, 권장 120FPS (기기에 따라 144Hz까지)

이유: VR에서 낮은 FPS는 어지러움을 유발하고 몰입도를 크게 떨어뜨림
즉, VR에서는 프레임 드랍을 절대적으로 막아야 함 → 무거운 후처리(Post Process)와 실시간 라이팅을 피하려는 경향

(2) VR에서 Post Process를 꺼리는 이유
Post Process는 화면 전체를 처리하는 효과(블룸, 필름 그레인, DOF, SSAO, 컬러 그레이딩 등)로, VR에서는 성능 저하뿐만 아니라 이상한 시각적 효과를 유발할 수도 있음.

- VR에서 문제가 될 수 있는 Post Process 효과들

- VR에서 안전한 Post Process 효과들

컬러 그레이딩 (Color Grading) → OK

톤 매핑 (Ton Mapping) → OK (Lumen이 아닌 기존 방식)

Vignette (비네트 효과, 화면 테두리 어둡게) → OK (멀미 방지에 도움될 수도 있음)

FXAA (Fast Approximate Anti-Aliasing) → OK (MSAA보다 VR에서는 가벼움)

결론: VR에서는 후처리(Post Process)를 최소한으로 유지하는 것이 일반적.


(3) 실시간 라이팅(VR에서도 사용 가능한가?)

VR에서도 실시간 라이팅을 쓸 수 있음. 다만 기본적으로 정적 라이팅(Static Lighting) 이 더 성능에 유리함

하지만 최신 VR 기기(GPU 성능이 좋은 경우)에서는 부분적으로 실시간 라이팅(Dynamic Lighting) 사용 가능

- 실시간 라이팅이 VR에서 논란이 되는 이유?

실시간 라이팅은 광원 계산이 매 프레임마다 이루어짐 → CPU/GPU 부담 큼

특히 Lumen 같은 고급 GI(Global Illumination) 시스템은 VR에서 잘 안 맞음

하지만 Shadow Map 기반의 실시간 라이팅은 성능을 조절하면 VR에서도 가능

- VR에서 라이팅 최적화 방법
결론:
VR에서는 기본적으로 정적 라이팅(Static Lighting)을 기본으로 사용

실시간 라이팅은 최소한으로 사용 (예: 중요한 캐릭터의 동적 그림자)

(실시간 라이팅도 감당 가능해보이는데 정적 라이팅을 굳이 구현할지는 모르겠다)


3. UAudioComponent VS USoundBase

USoundBase
USoundBase는 사운드 데이터를 저장하는 객체. 그냥 소리 파일 그 자체라고 보면 됨.
이걸 직접 재생할 수는 없고, UAudioComponent 같은 플레이어가 필요함.

- USoundBase의 대표적인 자식 클래스
USoundWave → WAV, MP3 같은 개별 사운드 파일
USoundCue → 여러 사운드를 믹싱하고 랜덤으로 재생할 수 있는 노드 시스템

-사용 예시 (사운드 자산 저장)
UPROPERTY(EditAnywhere, Category = "Sound")
USoundBase* MySound;

이렇게 선언하면 블루프린트에서 사운드 파일을 설정할 수 있음.


UAudioComponent
UAudioComponent – 사운드 플레이어 (재생 + 조작)
UAudioComponent는 실제로 소리를 재생하는 객체다.
소리를 틀고, 멈추고, 볼륨이나 피치를 실시간으로 변경할 수 있음.

USoundBase와 다르게 동적으로 생성할 수도 있고, 액터에 부착해서 3D 위치 기반으로 소리를 재생할 수도 있다.

- 사용 예시 (동적 생성 & 재생)
UAudioComponent* AudioComp = NewObject<UAudioComponent>(this);
AudioComp->SetSound(MySound); // USoundBase를 설정
AudioComp->Play();

이렇게 하면 UAudioComponent를 런타임에서 새로 생성해서 바로 소리를 재생할 수 있음.

* UAudioComponent 없이 소리 재생하는 방법

그냥 한 번만 사운드를 틀 거면 UAudioComponent 없이도 가능함.
-UGameplayStatics::PlaySoundAtLocation() 사용
-UGameplayStatics::PlaySoundAtLocation(this, MySound, GetActorLocation());

이렇게 하면 오브젝트 위치에서 바로 사운드가 재생됨.
근데 볼륨이나 피치를 실시간으로 변경할 수는 없음.


UAudioComponent vs USoundBase – 언제, 어떻게 써야 할까?

언리얼 엔진에서 소리를 재생할 때, USoundBase와 UAudioComponent를 선택하는 기준은 소리를 어떻게 사용하느냐에 따라 달라진다.

USoundBase는 사운드 데이터를 저장하는 용도다. SoundWave(WAV, MP3 파일)나 SoundCue(여러 사운드를 조합하는 노드 시스템)의 부모 클래스다.
이걸 직접 재생할 수는 없고, UAudioComponent 같은 오디오 플레이어에 연결해야만 소리가 난다.

반면, UAudioComponent는 소리를 실제로 재생하고 조작할 수 있는 컴포넌트다.
이걸 사용하면 소리를 틀고, 멈추고, 볼륨과 피치를 실시간으로 변경할 수 있다.
또한, 액터에 부착해서 3D 공간에서 특정 위치에서 소리가 나게 만들 수도 있다.

그래서 만약 소리를 한 번만 틀고 끝낼 거라면, 굳이 UAudioComponent를 만들 필요 없이, UGameplayStatics::PlaySoundAtLocation()을 사용하면 된다.
이 함수는 특정 위치에서 소리를 바로 재생해 주지만, 재생 중에 볼륨이나 피치를 변경할 수 없다는 단점이 있다.

하지만 만약 게임 내에서 특정 사운드를 실시간으로 조작해야 한다면 UAudioComponent를 써야 한다.
예를 들어, 차량 엔진 소리처럼 게임 중에 볼륨과 피치가 계속 변하는 경우에는 UAudioComponent를 사용해서 사운드를 동적으로 관리해야 한다.
SetVolumeMultiplier()나 SetPitchMultiplier() 같은 함수를 사용하면, 소리가 재생되는 동안에도 볼륨과 피치를 자유롭게 바꿀 수 있다.

그리고 만약 여러 개의 사운드를 조합해서 랜덤으로 재생해야 한다면, SoundCue를 사용하는 게 좋다.
SoundCue는 USoundBase의 한 종류로, 여러 개의 사운드를 믹싱하거나, 특정 확률로 랜덤하게 소리를 출력하는 기능이 있다.
즉, SoundCue를 사용하면 비슷한 효과음을 다양하게 조합해서 자연스러운 랜덤 효과음을 만들 수 있다.

결론적으로, 소리를 단순히 저장하려면 USoundBase, 한 번만 재생할 거면 PlaySoundAtLocation(), 실시간 조작이 필요하면 UAudioComponent, 랜덤한 사운드 믹싱이 필요하면 SoundCue를 선택하면 된다.
이 기준만 기억하면, 프로젝트에서 어떤 방식으로 사운드를 구현할지 쉽게 결정할 수 있다.


4. SkeletalMesh의 Socket 파츠 호환.
Continue...