언리얼 - 엔진 10 : Transform

김정환·2025년 4월 9일
0

Unreal Engine

목록 보기
11/24

Transform

  • AActorUObject 차이 : 월드에 배치 가능 여부
  • 단, AActor 만으로는 안되고 Transform의 기능을 가진 컴포넌트를 붙여주어야 정상적으로 사용할 수 있었음.
    • c++ Actor 클래스만 만들어도 배치되었던 이유는 언리얼이 내부적으로 임시 Transform을 붙여줬기 때문.
    • 그래서 배치까지는 되지만 그 이상의 조작은 불가능했음.
  • Actor의 Transform은 세가지 주요 속성이 있음.
    • 위치 Location
      • 월드에서 액터의 위치 표현
      • FVector(100.f, 200.f, 300.f) 형태로 표현
    • 회전 Rotation
      • 액터가 어느 방향을 바라보는지 어떤 각도로 기울어져 있는지 표현
      • 언리얼 C++에서 주로 FRotator(Pitch, Yaw, Roll) 형태로 표현
        • Roll : x축 회전. 좌우로 기울어지게 회전.
        • Pitch : y축 회전. 앞뒤로 기울어지게 회전.
        • Yaw : z축 회전. 좌우 방향 회전.
    • 크기 Scale
      • 액터의 크기 비율
      • FVector(1.0f, 1.0f, 1.0f) 형태로 표현
  • FTransform 자료형
    • 언리얼 엔진에서 위치, 회전, 스케일을 하나로 묶어 효율적으로 관리하기 위한 구조체
    • 구성 요소
      • Translation : 위치를 표현하는 FVector
      • Rotation : 회전을 표현하는 FRotator
      • Scale3D : 스케일을 표현하는 FVector
    • FTransform을 활용해서 세 가지 요소를 한 번에 다룰 수 있으므로,
      Transform 관련 연산을 보다 편리하게 처리 가능.

좌표계

월드 좌표

  • 게임 전체 월드를 기준으로 한 절대적인 좌표계
  • 액터 자체를 이동, 회전, 스케일할 때 대부분 월드 좌표계를 기준으로 함.
    • SetActorLocation(), GetActorLocation()

로컬 좌표 (상대 좌표)

  • 액터 자신이나 부모 액터 또는 부모 컴포넌트의 Transform을 기준으로 한 상대 좌표계
    • 즉, 상위 Transform을 원점으로 해서 얼마만큼 차이가 있는지 표현
  • 계층 구조가 있는 경우, 자식은 부모의 Transform에 종속되어 움직임.

계층 관계 : 부모 - 자식 관계

  • 액터에는 여러가지 컴포넌트가 붙을 수 있고
    최상위 Root Component를 기준으로 다른 컴포넌트들이 부착 Attach 관계를 맺을 수 있음.
  • 부모 액터가 이동, 회전, 스케일 변경되면 자식들은 상대 좌표값에 따라 함께 이동.
  • 부모-자식 관계가 맺어져 있다면 다음 함수를 통해 상대 좌표를 활용할 수 있음.
    • GetRelativeTransform()
    • SetRelativeLocation(), SetRelativeRotation()
  • 로컬 좌표계를 활용하면, 여러 컴포넌트들을 한번에 움직이거나, 특정 컴포넌트만 부모 기준으로 움직이게 할 수 있음.

주요 메서드

  • SetActorLocation(FVector NewLocation): 액터 위치 이동
  • SetActorRotation(FRotator NewRotation): 액터 회전
    • FRotator(Pitch : Y, Yaw : Z, Roll : X)
  • SetActorScale3D(FVector NewScale): 액터 스케일 변경
  • GetActorLocation(), GetActorRotation(), GetActorScale3D(): 현재 Transform 정보 가져오기
  • SetActorTransform(FTransform NewTransform): 위치·회전·스케일을 한 번에 설정

Tick 함수와 프레임 독립 로직

Tick(float DeltaTime)

  • 언리얼 엔진은 게임 실행 중 매 프레임마다 여러 작업을 수행
    1. 렌더링(Rendering) : 화면 그리기 (일반적으로 1초에 60프레임, 120프레임 등)
    2. 물리 연산 : 충돌·중력·마찰 등 물리 엔진 처리
    3. 오브젝트 업데이트 : 게임 내 액터들의 상태 갱신
  • 특정 액터가 “매 프레임마다” 수행할 로직이 있다면
    언리얼 엔진은 그 액터의 Tick(float DeltaTime) 함수를 매 프레임마다 호출.

Tick 활성화

  • 그냥 구현만 해둔다고 매 프레임 호출되는 것은 아니고 활성화시켜줘야 함.
    PrimaryActorTick.bCanEverTick = true;
    • c++ 클래스를 만들고 생성자 구현부를 보면 저렇게 활성화시켜주고 있음.
  • bCanEverTick 설정이 false면 성능 최적화를 위해 해당 액터의 Tick을 호출하지 않음.
    • 불필요한 Tick 호출은 성능에 부담
    • 사용하지 않는다면 false를 명시해주어 최적화 효과와 코드 명확성을 높여야 함.

DeltaTime

  • Tick 함수를 보면 매개변수로 DeltaTime이라는 실수값을 주고 있음.
  • DeltaTime : 직전 프레임부터 현재 프레임까지 걸린 시간(초)
    • 60 FPS 경: DeltaTime ≈ 1/60초 ≈ 0.0167초
    • 120 FPS 환경: DeltaTime ≈ 1/120초 ≈ 0.0083초
    • 유니티의 Time.deltaTime와 동일

프레임 레이트가 높을수록 DeltaTime이 작아지고, 낮을수록 DeltaTime이 커집니다.

DeltaTime을 활용한 프레임 독립적인 로직

  • 단순히 매 프레임 X축으로 1 움직인다고 하면, FPS가 더 높게 나오는 컴퓨터에서는 그렇지 못한 컴퓨터보다 더 많이 X축으로 움직이는 상황이 발생함.
  • 이를 방지하려면, DeltaTime을 곱해서 초 단위 기준으로 이동·회전을 계산해야함.
    • 예) 초당 100만큼 이동하고 싶다면: 100 * DeltaTime을 매 프레임마다 더해줌
      • 60 FPS → 한 프레임당 1.67씩 이동, 60 프레임 곱하면 100
      • 120 FPS → 한 프레임당 0.83씩 이동, 120 프레임 곱하면 100
    • 이처럼 어느 FPS 환경에서도 동일한 실제 속도를 유지할 수 있음.
profile
만성피로 개발자

0개의 댓글