블루프린트로 구현해봤던 액터의 이동을 C++ 클래스를 통해 다시 재현하려면 좌표와 속도 등에 대한 변수와 이전에 블루프린트에서 사용했던 여러 함수(노드)들을 사용해야한다.
우선 레벨에 배치했던 C++ 클래스 MovingPlatform 을 눈으로 확인하기 위해 큐브 컴포넌트를 추가해준다.
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
FVector f = FVector(0.0,0.0,0.0);
이제 헤더 파일에 FVector 변수 하나를 추가
void AMovingPlatform::BeginPlay()
{
Super::BeginPlay();
f = FVector(-13730.0, -12120.0, 4876.0); //게임 실행 시 보이는 위치
SetActorLocation(f)
}
구현 파일 BeginPlay 함수에 특정 위치 값을 넣어주고 이를 SetActorLocation 함수의 매개변수로 넣어주고 게임을 실행해본다.
처음 보이는 화면 바로 앞에 (임의로 지정한 좌표) 해당 액터가 위치한 모습을 볼 수 있다.
앞서 블루프린트에서 사용해봤듯이 BeginPlay 는 게임 시작 시 한 번 호출되는 함수이며, Tick 함수 또한 매 프레임마다 호출되는 함수이다. 이를 이용해 간단하게 액터를 움직일 수 있다.
void AMovingPlatform::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
f.Z += 1;
SetActorLocation(f);
}
Tick 함수 내에 FVector 변수 f 의 Z 값에 대해 접근하여 한 프레임 당 1씩 늘어나게끔 설정한다. 그리고 다시 SetActorLocation 함수를 통해 액터의 위치를 설정해준다.

Tick 함수를 통해 Z 값이 점점 올라가는 모습을 볼 수 있다.
이제 한가지 조건을 추가해서 간단하게 같은 자리를 반복해서 이동하는 플랫폼을 만들 수 있다.
UPROPERTY(EditAnywhere)
FVector StartLocation;
UPROPERTY(EditAnywhere)
float Distance;
헤더 파일에서 2개의 변수를 추가
void AMovingPlatform::BeginPlay()
{
Super::BeginPlay();
f = FVector(-13730.0, -12120.0, 4876.0);
SetActorLocation(f);
StartLocation = GetActorLocation();
move = 1;
}
void AMovingPlatform::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
f.Y += move;
SetActorLocation(f);
Distance = FVector::Dist(f, StartLocation);
if (Distance > 100) move *= -1;
}
구현 파일에서는 BeginPlay 함수에서 StartLocation 을 해당 액터의 초기 위치값으로 설정하고 move 도 양수 1로 설정한다. 이후에 Tick 함수에서 FVector 의 Dist 함수를 통해 현재 위치: f 의 값과 처음 위치: StartLocation 을 비교해 그 값이 100을 초과한다면 move 의 값을 음수로 반전시키기를 반복해준다.
그렇다면 해당 액터가 Distance 와 그 조건에 맞는 거리를 왕복한다.
여태까지 해당 액터는 그저 초기 위치에서 Y 값에 +1 혹은 -1 로 이동할 뿐 속도라는 개념이 없이 SetActorLocation 으로 간단하게 이동만을 구현했다. 이제 Velocity 라는 FVector 변수를 선언하여 해당 플랫폼에게 속도를 구현해보자
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
FVector CurrentLocation = FVector(0.0,0.0,0.0);
UPROPERTY(EditAnywhere)
FVector StartLocation;
UPROPERTY(EditAnywhere)
float MoveDistance = 1000;
UPROPERTY(EditAnywhere)
FVector Velocity = FVector(0.0,100.0,0.0);
};
먼저 헤더 파일에서 앞서 이동에 사용되는 move 변수를 지우고 위와 같이 변수들을 선언한다. GetActorLocation 으로 값을 받아오던 f 는 CurrentLocation 을 변경하고 총 이동할 거리를 설정할 변수인 MoveDistance 를 float 형으로 선언한다. 마지막으로 속도(+방향)을 설정할 Velocity 는 FVector 로 선언한다.
void AMovingPlatform::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
CurrentLocation = GetActorLocation();
SetActorLocation(CurrentLocation + Velocity * DeltaTime);
float Distance = FVector::Dist(CurrentLocation, StartLocation);
if (Distance > MoveDistance)
{
FVector Direction = Velocity.GetSafeNormal();
StartLocation = StartLocation + Direction * MoveDistance;
SetActorLocation(StartLocation);
Velocity *= -1;
}
}
코드를 하나씩 살펴보자면 다음과 같다.
SetActorLocation(CurrentLocation + Velocity * DeltaTime);기존의 단순하게 액터의
Y값에 접근해+1-1하던 방식과 다르게Velocity와DeltaTime으로 액터를 이동시켜야한다.Velocity는Y값이 100.0 으로 설정되어 있으므로DeltaTime없이 바로SetActorLocation으로 들어가면 액터가 순간이동할 것이다.
float Distance = FVector::Dist(CurrentLocation, StartLocation);기존의 내용과 같지만 헤더 파일에 선언되어 있던
Distance를 지역변수로 전환했음
if (Distance > MoveDistance)이전과 같으나 100 이라고 사용하던 값을 변수
MoveDistance로 변경함
FVector Direction = Velocity.GetSafeNormal();
FVector의 멤버 함수인GetSafeNormal을 통해 정규화를 하여 방향을 구한다. 값을 제공한Velocity와는 다르게 단순히 방향만을 나타낸다.
StartLocation = StartLocation + Direction * MoveDistance; SetActorLocation(StartLocation); Velocity *= -1;초기 위치값을 저장하는
StartLocation의 값을 업데이트하고 액터를 그 위치에 설정하면서Velocity의 값을 반전시켜준다.
간단하게 요약하자면 다음과 같다.
Velocity)를 기반으로 새 위치로 이동 (DeltaTime: 시간과 함께 사용)Dist 함수를 통해 초기 위치와 현재 위치 거리 비교MoveDistance) 이상 이동했다 ?Direction)을 구함 (Velocity 정규화)