언리얼 Transform 관련 예제이다
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestActor.generated.h"
UCLASS()
class PHYSICSANIMATIONCPP_API ATestActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
void PrintData();
void DrawTransform(FTransform T);
private :
int DrawCnt;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "TestActor.h"
#include "DrawDebugHelpers.h"
// Sets default values
ATestActor::ATestActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
DrawCnt = 0;
}
// Called when the game starts or when spawned
void ATestActor::BeginPlay()
{
Super::BeginPlay();
FTransform Current = GetActorTransform();
UE_LOG(LogTemp, Warning, TEXT("Current transform : %s"), *Current.ToString());
DrawTransform(Current);
FTransform A = Current;
FTransform B = Current;
FVector AddLoc = FVector(100, 0, -100);
FQuat AddRot = FQuat::MakeFromEuler(FVector(0, 30, 15));
FTransform AddTrans = FTransform(AddRot, AddLoc);
B.Accumulate(AddTrans);
UE_LOG(LogTemp, Warning, TEXT("Add Loc : %s Add Rot : %s"), *AddLoc.ToString(), *AddRot.Euler().ToString());
UE_LOG(LogTemp, Warning, TEXT("Moved transform : %s"), *B.ToString());
DrawTransform(B);
FTransform Relative = B.GetRelativeTransform(A);
UE_LOG(LogTemp, Warning, TEXT("Relative transform : %s"), *Relative.ToString());
A = Relative * A;
UE_LOG(LogTemp, Warning, TEXT("Restore transform : %s"), *A.ToString());
DrawTransform(A);
}
// Called every frame
void ATestActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ATestActor::PrintData()
{
UE_LOG(LogTemp, Warning, TEXT("Print transform : %s"), *GetActorTransform().ToString());
}
void ATestActor::DrawTransform(FTransform T)
{
FVector Loc = T.GetLocation();
if (DrawCnt == 0)
{
DrawDebugSphere(GetWorld(), Loc, 10, 26, FColor::Black, true, -1, 0, 2);
}
else
{
DrawDebugSphere(GetWorld(), Loc, 10, 26, FColor::White, true, -1, 0, 2);
}
DrawCnt++;
FVector Forward = T.GetUnitAxis(EAxis::X);
FVector Right = T.GetUnitAxis(EAxis::Y);
FVector Up = T.GetUnitAxis(EAxis::Z);
float Length = 100 + DrawCnt * 25;
DrawDebugDirectionalArrow(GetWorld(), Loc, Loc + Forward * Length, 50.f, FColor::Red, true, -1.f, 0, 5.f);
DrawDebugDirectionalArrow(GetWorld(), Loc, Loc + Right * Length, 50.f, FColor::Green, true, -1.f, 0, 5.f);
DrawDebugDirectionalArrow(GetWorld(), Loc, Loc + Up * Length, 50.f, FColor::Blue, true, -1.f, 0, 5.f);
}
Location, Rotation 간의 차이를 구하는 방법과, Transform 사이의 Blend 값을 구하는 방법이다.
void ATestActor::Test2()
{
FTransform Current = GetActorTransform();
UE_LOG(LogTemp, Warning, TEXT("Current transform : %s"), *Current.ToString());
FTransform A = Current;
FTransform B = Current;
FTransform C = Current;
FVector AddLoc = FVector(100, 0, -100);
FQuat AddRot = FQuat::MakeFromEuler(FVector(0, 45, 30));
FTransform AddTrans = FTransform(AddRot, AddLoc);
UE_LOG(LogTemp, Warning, TEXT("AddTrans transform : %s"), *AddTrans.ToString());
B.SetLocation(B.GetLocation() + AddLoc);
B.SetRotation(B.GetRotation() * AddRot);
DrawTransform(A);
DrawTransform(B);
FVector DeltaLoc = B.GetLocation() - A.GetLocation();
FQuat DeltaRot = A.GetRotation().Inverse() * B.GetRotation();
// Lerp
C.SetLocation(C.GetLocation() + DeltaLoc);
C.SetRotation(C.GetRotation() * DeltaRot);
DrawTransform(C);
// delta
for (int i = 1; i <= 4; ++i)
{
float Size = i * 0.2f;
FTransform D = Current;
D.FTransform::Blend(A, B, Size);
DrawTransform(D);
}
UE_LOG(LogTemp, Warning, TEXT("DeltaLoc : %s DeltaRot : %s"),
*DeltaLoc.ToString(), *DeltaRot.Rotator().ToString() );
}
Transform을 이용하여 Vector를 변환하는 예제이다.
void AMathTestGameMode::TransformVectorExample(const FTransform& T)
{
FVector Direction = (FVector::ForwardVector + FVector::RightVector).GetSafeNormal();
// T를 World로 하는 변환
FVector Transformed = T.TransformVector(Direction);
// T를 Local로 하는 변환
FVector InverseTransformed = T.InverseTransformVector(Direction);
FVector Start = FVector::ZeroVector + FVector(0, 0, 100);
FVector SourceEnd = Start + Direction * 100.0f;
FVector TransformedEnd = Start + Transformed * 100.0f;
UWorld* World = GetWorld();
GameUtils::DrawArrow(GetWorld(), Start, SourceEnd, FColor::Blue);
GameUtils::DrawArrow(GetWorld(), Start, TransformedEnd);
}
'게임 엔진 > Unreal' 카테고리의 다른 글
[Unreal] Interface 이용 방법 (0) | 2020.10.04 |
---|---|
[Unreal] [Example] Animation에서 Physics Velocity 계산 (0) | 2020.09.09 |
[Unreal] [Editor] Slate를 이용한 커스텀 에디터 List View 제작 (0) | 2020.06.29 |
[Unreal] [Editor] 프로퍼티 에디터 제작 방법 (0) | 2020.06.26 |
[Unreal] [Example] 객체 직렬화 방법 (0) | 2020.06.25 |