핵심 함수
GetActorLocation() : 현재 엑터의 위치 FVector를 가져오는 함수
SetActorLocation() : 현재 액터의 위치를 "변경"하는 함수핵심 함수
목표
c++클래스를 생성
시작지점과 이동거리, 이동속도를 변수로 지정
두 지점을 왕복하는 로직 작성
Actor를 상속받는 C++클래스 생성
DefaultMovingActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DefaultMovingActor.generated.h"
UCLASS()
class HOMEWORK6_API ADefaultMovingActor : public AActor
{
GENERATED_BODY()
public:
ADefaultMovingActor();
UPROPERTY(EditAnywhere, Category = "Components")
USceneComponent* SceneRoot;
UPROPERTY(EditAnywhere, Category = "Components")
UStaticMeshComponent* StaticMeshComp;
UPROPERTY(VisibleInstanceOnly, Category="Movement")
FVector StartLocation;
UPROPERTY(EditInstanceOnly, Category = "Movement")
float MoveSpeed;
UPROPERTY(EditInstanceOnly, Category = "Movement")
FVector MaxRange;
private:
int direction = 1;
FVector TargetLocation;
protected:
virtual void BeginPlay() override;
virtual void OnConstruction(const FTransform& Transform) override;
virtual void Tick(float DeltaTime) override;
};
SceneComponent를 루트로 두고
StaticMeshComponent를 추가
시작점, 이동위치, 이동속도 변수 3개를 선언하고, 각각 매크로를 이용해 리플렉션에 등록.
DefaultMovingActor.cpp
#include "DefaultMovingActor.h"
// Sets default values
ADefaultMovingActor::ADefaultMovingActor()
{
PrimaryActorTick.bCanEverTick = true;
MoveSpeed = 300.f;
MaxRange = FVector(100.f, 100.f, 0);
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
SetRootComponent(SceneRoot);
StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
StaticMeshComp->SetupAttachment(RootComponent);
}
// Called when the game starts or when spawned
void ADefaultMovingActor::BeginPlay()
{
Super::BeginPlay();
TargetLocation = StartLocation + MaxRange;
UE_LOG(LogTemp, Error, TEXT("TargetLocation : %f, %f, %f"), TargetLocation.X, TargetLocation.Y, TargetLocation.Z);
}
void ADefaultMovingActor::OnConstruction(const FTransform& Transform)
{
//에디터 상의 값이 갱신될 때 마다 호출되는 함수임.
//디테일 패널 값을 건드려도 갱신이 된다.
Super::OnConstruction(Transform);
StartLocation = GetActorLocation();
}
// Called every frame
void ADefaultMovingActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (FVector::Dist(GetActorLocation(), StartLocation) <= 20) {
direction = 1;
UE_LOG(LogTemp, Error, TEXT("straight"));
}
if (FVector::Dist(GetActorLocation(), TargetLocation) <= 20) {
direction = -1;
UE_LOG(LogTemp, Error, TEXT("reverse"), TargetLocation.X, TargetLocation.Y, TargetLocation.Z);
}
FVector moveDirection = (TargetLocation - StartLocation).GetSafeNormal();
float stepMove = MoveSpeed * DeltaTime;
FVector stepLocation = GetActorLocation() + moveDirection * stepMove * direction;
SetActorLocation(stepLocation, true);
}
생성자에서는 속도, 이동위치의 기본값을 설정하고
루트컴포넌트와 스태틱 메시 컴포넌트를 초기화.
BeginPlay()
시작지점 StartLocation과 이동거리 MaxRange를 더해 목표지점을 초기화
OnConstruction()
BeginPlay와 비슷한데, 생성될때와 좌표가 이동되는 등 값이 갱신될 때 마다 호출됨.
해당 이벤트에서 값을 갱신하여 시작지점이 항상 액터가 위치한 지점이 되도록 해두었음.
Tick()
실행되는 매 프레임마다 호출되는 이벤트,
실제 움직임을 구현할 위치.
액터의 현재 위치를 통해 이동할 방향을 확인한 후에
두 지점 벡터를 통해 방향 정규 벡터(크기가 1이고 방향을 가진 벡터)를 구하고,
이동속도 X DeltaTime X 방향값을 모두 곱하여 이번 프레임에 이동할 값을 구해 SetActorLocation로 위치를 이동시킨다.
현재 코드에서 예상되는문제 :
만약 랙이 걸리는 등의 이유로 크게 움직여, 시작지점과 목표지점 두 지점을 넘어가버리게 되면 영영 돌아오도록 하지 못한다.
이를 해결하기 위해 두 지점에 도달하거나 넘어가는 조건을 더 확실하게 개선해야 할 것이다.
개선방안.
목표지점을 명확하게 관리하고, 목표지점을 향해 정확히 도달 한 후 다음 지점을 찾도록 변경.
추가 개선목표 : 두 지점이 아닌, 3개 이상의 여러 지점을 거쳐 이동하도록 개선 및 왕복을 할것인지 말것인지 여부를 선택 가능하도록 변경
'개발 > 언리얼' 카테고리의 다른 글
| 언리얼 C++ 펜듈럼 움직임 구현하기 (0) | 2026.04.10 |
|---|---|
| 언리얼 빌드 이해하기(UBT, UHT, CDO, GC) (0) | 2026.04.10 |
| 언리얼 리플렉션 매크로로 프로퍼티 설정하기(UPROPERTY, UFUNCTION) (0) | 2026.04.07 |
| 액터의 생명주기 간단하게 정리 (0) | 2026.04.07 |
| c++ 액터 클래스 뼈대 만들기 (0) | 2026.04.07 |