오늘 배운 것
1. Actor와 Transfrom
- Actor는 언리얼 엔진에서 월드에 존재하는 모든 오브젝트를 의미한다.
건물, 캐릭터, 아이템 등 눈에 보이는 모든 것들이 액터로 표현된다.
- 액터에는 세 가지 중요한 속성이 있다. (이 세 가지 속성을 Transform이라고 한다.)
위치 (Location)
: 액터가 월드에서 어느 지점에 있는지를 나타낸다.
FVector(0.0f, 0.0f, 0.0f) 형태로 표현한다.
회전 (Rotation)
: 액터가 어느 방향을 바라보는지, 어떤 각도로 기울어져 있는지를 나타낸다.
언리얼 C++ 에서는 주로 FRotator(Pitch, Yaw, Roll) 형태로 표현한다.
- Roll : 좌우로 기울어지는 회전 (x축을 축으로 하는 회전)
- Pitch : 앞뒤 방향의 기울어짐 (y축을 축으로 하는 회전)
- Yaw : 좌우 방향 회전 (z축을 축으로 하는 회전)
스케일 (Scale)
: 액터의 크기 비율.
FVector(X, Y, Z) 형태로 표현한다.
- FTransform 자료형
: 언리얼 엔진에는 위치, 회전, 스케일을 하나로 묶어 효율적으로 관리하기 위한 구조체인 FTransform이 있다.
- FTransform은 내부적으로 다음 세 요소를 보관한다.
: Translation : 위치를 표현하는 FVector
: Rotation : 회전을 표현하는 FRotator
: Scale3D : 스케일을 표현하는 FVector
FTransform을 활용하면 위치/회전/스케일을 한 번에 다룰 수 있어, Transfrom 관련 연산을 보다 편리하게 처리할 수 있다.
- 좌표계의 개념
: 월드 좌표계 (World Space)
- 게임 전체를 기준으로 한 절대적인 좌표계이다.
- SetActorLocation(), GetActorLocation() 처럼 액터 자체를 이동/회전/스케일할 때 대부분 월드 좌표계를 기준으로 한다.
: 로컬 좌표계 (Local Space)
- 액터 자신이나 부모 액터 (또는 부모 컴포넌트)의 Transform 기준으로 한 상대적인 좌표계이다.
- 계층 구조 (부모-자식 관계)가 있는 경우, 자식은 부모의 Transform에 종속되어 움직인다.
- 부모-자식 관계가 맺어져 있다면,
: GetRelativeTransform() : 부모 기준의 상대 위치/회전/스케일을 가져온다.
: SetRelativeLocation(), SetRelativeRotation() : 부모 기준으로 자식의 위치/회전/스케일을 조정
2. C++ 코드로 Transform 다루기
- Transform 조정 함수
: 게임 로직에서 액터의 Transform을 변경하고 싶다면, C++ 또는 블루프린트 함수를 사용한다.
대표적인 함수들은 아래와 같다.
- SetActorLocation(FVector NewLocation) : 액터 위치 이동
- SetActorRotation(FRotator NewRotation) : 액터 회전
- SetActorScale3D(FVector NewScale) : 액터 스케일 변경
- GetActorLocation(), GetActorRotation(), GetActorScale3D() : 현재 Transform 정보 가져오기
- SetActorTransform(FTransform NewTransform) : 위치/회전/스케일을 한 번에 설정
3. Tick 함수와 프레임 독립적인 로직 이해하기
- 게임 프레임 업데이트와 Tick
: 언리얼 엔진은 게임 실행 중 매 프레임마다 여러 작업을 수행한다.
- 렌더링(Rendering) : 화면 그리기 (일반적으로 1초에 60프레임, 120프레임 등)
- 물리 연산 : 충돌/중력/마찰 등 물리 엔진 처리
- 오브젝트 업데이트 : 게임 내 액터들의 상태 갱신
: 특정 액터가 "매 프레임마다" 수행할 로직이 있다면, 언리얼 엔진은 그 액터의 Tick(float DeltaTime) 함수를 매 프레임 호출한다.
- Tick 함수 활성화 하기
: 액터를 생성할 때 기본적으로 Tick() 함수를 사용하려면, 아래와 같이 생성자에서 설정해야 한다.
PrimaryActorTick.bCanEverTick = true;
: bCanEverTick가 false면 엔진은 성능 최적화를 위해 해당 액터의 Tick을 호출하지 않는다.
불필요한 Tick 호출은 성능에 부담을 주기에, 사용하지 않는다면 false를 명시하여 최적화 효과와 코드 명확성을 높일 수 있다.
- DeltaTime 이란?
: Tick(float DeltaTime) 함수에서 Deltatime은 "직전 프레임부터 현재 프레임까지 걸린 시간(초)" 이다.
- 60 FPS경 : DeltaTime ≈ 1/60초 ≈ 0.0167초
- 120 FPS경 : DeltaTime ≈ 1/120ch ≈ 0.0083초
프레임 레이트가 높을 수록 Deltatime이 작아지고, 낮을수록 DeltaTime이 커진다.
- DeltaTime을 활용한 프레임 독립적인 움직임
: 단순히 "매 프레임마다 X 좌표를 1씩 증가" 시키면, FPS가 높을 수록 더 빨리 움직여 게임 체감 속도가 달라지게 된다.
이를 방지하려면 DeltaTime을 곱해서 초 단위 기준으로 이동/회전을 계산해야 한다.
ex) 초당 100 만큼 이동하고 싶다면 : 100 * DeltaTime을 매 프레임마다 더해준다.
- 60 FPS -> 한 프레임 당 1.67씩 이동
- 120 FPS -> 한 프레임 당 0.83씩 이동
4. Tick 함수와 DeltaTime을 활용한 회전 구현하기
- 회전 속도 변수와 Tick 함수 선언
: 이동 뿐 아니라 회전도 마찬가지로 DeltaTime을 곱해주면, 초당 일정 각도로 회전하는 것을 쉽게 구현할 수 있다.
// 회전 속도를 나타내는 변수(초당 도(degrees) 단위)
float RotationSpeed;
virtual void Tick(float DeltaTime) override;
item.h
- Tick 함수에서 DeltaTime으로 회전 구현
#include "Item.h"
AItem::AItem()
{
// Tick 함수를 켜줍니다.
PrimaryActorTick.bCanEverTick = true;
// 기본 회전 속도 (1초에 90도 회전)
RotationSpeed = 90.0f;
}
void AItem::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// RotationSpeed가 0이 아니라면 회전 처리
if (!FMath::IsNearlyZero(RotationSpeed))
{
// 초당 RotationSpeed만큼, 한 프레임당 (RotationSpeed * DeltaTime)만큼 회전
AddActorLocalRotation(FRotator(0.0f, RotationSpeed * DeltaTime, 0.0f));
}
}
item.cpp
- FMath::IsNearlyZero는 부동소수점 비교에서 안전하게 0에 가까운지 확인해주는 함수이다.
- RotationSpeed = 360.0f 면 1초에 한바퀴(360도) 회전, 180.0f 면 2초에 한바퀴 회전하게 된다.
- AddActorLocalRotation()은 액터의 로컬 기준으로 회전을 추가해주는 함수이다.
오늘 배운 것에서 개인적으로 중요하다고 생각하는 것
Deltatime
: 직전 프레임부터 현재 프레임까지 걸린 시간(초)
'본캠프 TIL' 카테고리의 다른 글
| 06.09 Unreal 본캠프) 3번 과제 회전발판과 움직이는 장애물 (0) | 2026.06.09 |
|---|---|
| 06.08 Unreal 본캠프) C++ 클래스와 리플렉션 시스템 (0) | 2026.06.08 |
| 06.08 Unreal 본캠프) 언리얼 C++ Log 출력 (0) | 2026.06.08 |
| 06.05 Unreal 본캠프) 언리얼 C++ Actor에 대해서 (0) | 2026.06.05 |
| 06.01 Unreal 본캠프) 커리어 데이 (0) | 2026.06.01 |