[내일배움캠프] 간단한 좌표 이동 프로그램

김세희·2025년 6월 16일
post-thumbnail

✍️Today I Learned

  1. 간단한 좌표 이동 프로그램(UE + C++)

필수 기능

  1. 액터가 스폰되는 시점에 동작하도록 구현한다.
  2. 시작점은 (0, 0)이고 캐릭터가 랜덤하게 10회 이동한다.
  3. 이동할 때 마다 죄표를 출력한다.
  4. 한 번 이동할 때 이동한 x, y좌표가 2미만이어야 한다.
  5. 로그 출력은 UE_LOG를 활용한다.
  6. Step()은 0 혹은 1을 랜덤으로 반환한다.
  7. Move()는 10회 움직이면서 좌표를 출력한다.

도전 기능

  1. 10회 이동시 각 스텝마다 이전 좌표 기준 이동거리를 계산하여 출력한다.
  2. 각 스텝마다 50% 확률로 랜덤하게 이벤트가 발생하며 발생 여부를 출력한다.
  3. 10회 이동 후에 총 이동 거리와 총 이벤트 발생 횟수를 출력한다.

구현 요약

언리얼에서 액터 C++ 클래스를 생성 후 C++로 동작을 구현했다.
필수 + 도전 기능에 액터가 실제로 이동하고 Move()가 1초 간격으로 10회 실행되도록 하는 기능을 추가했다.

클래스 다이어그램

출력 로그

실행 영상

문제 해결 과정

  1. C++ 빌드가 Unreal에서 반영되지 않음
    -> Visual Studio의 솔루션 구성의 Development Editor로 설정 후 빌드

  2. UE_LOG에서 *FString
    UE_LOG(LogTemp, Log, TEXT("String: %s"), *FString());
    %s는 TCHAR*를 받기 때문에 *FString()을 사용해야 한다.

  3. 랜덤 숫자 출력
    min ~ max 사이의 랜덤한 정수를 출력한다.

FMath::RandRange(min, max);
  1. 로그 카테고리 추가
    Log를 편하게 보기 위해 LogMyActor라는 카테고리를 추가하여 필터링했다.
// 헤더
DECLARE_LOG_CATEGORY_EXTERN(LogMyActor, Log, All);
// cpp
DEFINE_LOG_CATEGORY(LogMyActor);
  1. Static Mesh Component 추가
    스태틱 메쉬 컴포넌트를 추가하고 루트 컴포넌트로 설정했다.
    스태틱 메쉬는 언리얼에서 변경했다.

  2. UPROPERTY(EditAnywhere)
    Start(액터 시작위치), Event Probability(이벤트 발생 확률), TotalMoveCount(총 이동 횟수) 는 언리얼 에디터에서 변경할 수 있도록 EditAnywhere로 설정했다.

  1. Timer
    함수를 일정 시간마다 실행하는 함수. 참고 문서
    Move()로 변경한 벡터를 기반으로 SetActorLocation()을 하도록 추가했다. 움직임을 화면에서 확실히 볼 수 있도록 Move()를 1초마다 실행하게 했다.
    ❗TimerHandle을 헤더에 꼭 정의해야 한다. FTimerHandle MemberTimerHandle;
void AMyActor::BeginPlay()
	{
		Super::BeginPlay();
		// RepeatingFunction 을 1초에 한 번 실행
		GetWorld()->GetTimerManager().SetTimer(
        	MemberTimerHandle,	// 타이머 관리 핸들. 헤더에 정의 필요 
            this, 	// 함수가 소속된 객체
            &AMyActor::RepeatingFunction,	//실행할 함수 포인터 
            1.0f, 	// 실행 간격 (초)
            true, 	// 반복 여부 (false = 한 번 실행)
    	);
	}

	void AMyActor::RepeatingFunction()
	{
		// 이 함수를 충분히 호출했으면, 타이머를 해제합니다.
		if (--RepeatingCallsRemaining <= 0)
		{
			GetWorld()->GetTimerManager().ClearTimer(MemberTimerHandle);
			// 타이머 해제 이후 MemberTimerHandle 다른 타이머에 재사용 가능
		}
		// 이후 코드 실행
	}

0개의 댓글