본문 바로가기

숙제

5번 과제(UE_LOG로 2차원 움직임 출력하기)

필수기능

새로운 엑터를 생성하고 엑터가 spawn 되는 시점에 동작되도록 아래 요구사항대로 동작하도록 코드를 구현 합니다

시작점(0,0) 있는 게임 캐릭터가 랜덤하게 10회 이동 합니다. 각 스텝에서 거쳐간 좌표를 모두 출력하는게 목적입니다.

세부 요구사항은 아래와 같습니다.

  • 시작점은 (0,0)이고 한번 이동시 x좌표와 y좌표 모두 2이상 이동할 수 없습니다. 예를 들면 아래와 같습니다.
    • (0,0) 에서 (1,2)은 이동할수 없습니다. y좌표가 2이상 이동했기 때문입니다.
    • (0,0)에서 (1,1)은 이동할 수 있습니다. x좌표 y좌표 모두 2미만 이동했기 때문 입니다.
  • 이동은 입력을 받는게 아니고 10회 모두 랜덤으로 움직입니다.
  • 매번 이동시 현재 좌표를 출력할 수 있어야 합니다.
  • 로그 출력은 UE_LOG를 활용합니다.
  • step 함수는 x좌표 y좌표 각각 이동할 거리 입니다.
    • 예를들어서 현재 좌표가(x1,y1)이라면 다음 좌표는 (x1+step 함수의 리턴값,y1 + step함수의 리턴 값) 입니다.
    • step함수는 0혹은 1을 랜덤으로 반환 합니다.
  • move함수는 (0,0)부터 10회 움직이면서 좌표를 출력합니다. 이동시 step 함수가 활용 됩니다.

이를 구현한다면 아래와 같은 클래스가 될 것 입니다.(꼭 따라하실 필요는 없고 참고만 하세요)


1. x, y 각 50%확률로 1 움직이기

2. 이동횟수 10번 카운트하기

void AMove_2D::step() // step함수 생성, 헤더에 void step();
{
	int32 x = 0; // x 좌표 값
	int32 y = 0; // y 좌표 값
	int32 count = 0; // 이동횟수 카운트
	int32 randomX, randomY; // 확률 대입할 변수

	UE_LOG(LogTemp, Error, TEXT("move start")); // 이동 시작 출력

	while (count < 10)
	{
		randomX = FMath::RandRange(0, 1); // X에 50%확률 주기
		randomY = FMath::RandRange(0, 1); // Y에 50%확률 주기
		if (randomX == 1) // 50%확률로 X 이동
		{
			x += 1;
		}
		if (randomY == 1) // 50%확률로 Y 이동
		{
			y += 1;
		}
		UE_LOG(LogTemp, Warning, TEXT("Current Location(%d, %d)"), x, y); // 이동한 좌표 출력
		++count; // 이동횟수 증가
	}
	UE_LOG(LogTemp, Error, TEXT("move end")); // 이동 끝 출력
}

// Called when the game starts or when spawned
void AMove_2D::BeginPlay()
{
	Super::BeginPlay();

	step(); // 함수 호출
	
}

좌표가 랜덤하게 10번 출력된다.(좌표 +2 없음)


도전기능

필수 기능 구현을 완료한 후 아래 기능을 추가 힙니다.

  • 10회 이동시 각 스텝마다 이전 좌표기준 이동 거리를 계산해서 출력 합니다. 이동 거리는 아래와 같이 계산 합니다.

  • 10회 이동시 각 스텝마다, 50% 확률로 랜덤하게 이벤트가 발생합니다.(발생 시키는 부분도 구현하셔야 합니다.) 각 스텝마다 이벤트 발생여부를 출력합니다.
  • 10회 이동후에는 총 이동거리와 총 이벤트 발생횟수를 출력 합니다.

이를 구현한다면 아래와 같은 클래스가 될 것 입니다.(꼭 따라하실 필요는 없고 참조만 하세요)


도전기능을 구현하기 위해 주어진 사진을 참고하여 클래스를 만들어 봤다

 

우선 필수 기능에서 하나의 step 함수로 구현한 것을 두 함수로 기능을 나눴다.

step 함수는 50%확률을 구하여 값을 반환하고 move 함수는 step값을 이용하여 좌표를 이동시키는 함수이다.

int32 AMove_2D::step() // 50% 확률구하기
{
	if (FMath::RandRange(0, 1))
	{
		return 1;
	}
		return 0;
}

void AMove_2D::move() // 이동하기
{
	int32 x = 0; // x 좌표 값
	int32 y = 0; // y 좌표 값
	int32 count = 0; // 이동횟수 카운트

	UE_LOG(LogTemp, Error, TEXT("move start, Current Location(%d, %d)"), x, y); // 이동 시작 좌표 출력

	while (count < 10)
	{
		if (setp() == 1) // 50%확률로 x 이동
		{
			x += 1;
		}
		if (step() == 1) // 50%확률로 y 이동
		{
			y += 1;
		}

	UE_LOG(LogTemp, Warning, TEXT("Current Location(%d, %d)"), x, y); // 이동 후 좌표
    	++count; // 이동 횟수 증가
	}
}

이제 도전기능인 이동 거리 구하기.

사진으로 공식을 줬지만 루트를 어떻게 구현할지 몰라서 인터넷을 보고 sqrt라는 함수(언리얼에서는 FMath::Sqrt)를 사용하면 루트가 된다 하여 응용했다.

float AMove_2D::distance(FVector2D a, FVector2D b) // 두 좌표 거리 구하기
{
	return FMath::Sqrt((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
}

두 좌표를 구하는 기능은 FVector2D::distance(a,b)를 이용하면 좌표 a와 b의 직선거리를 구하여 쉽게 구해지지만 지금은 배우는 단계이니 과제에서 준 공식을 이용하여 함수를 구현했다.

 

다음은 각 스텝마다 50%확률로 랜덤하게 이벤트 발생하고 발생여부를 출력하기를 구현하려는데 이건 step 함수와 동일하게 그냥 50%확률을 구하는 기능만 구현했다. 어떤 다른것을 더 해야할지 모르겠다.

int32 AMove_2D::createEvent() // 50% 확률구하기 이벤트용
{
	if (FMath::RandRange(0, 1))
	{
		return 1;
	}
	return 0;
}

위 기능들을 모두 move함수에서 사용하고 출력까지 하도록 합쳤었는데 갑자기 move에는 이동하는 기능만 넣어두고 나머진 BeginPlay에 구현을 해보는게 좋을 것 같아서 다시 수정을 했다.

void AMove_2D::move()
{
	if (step() == 1)
	{
		location.X += 1;
	}
	if (step() == 1)
	{
		location.Y += 1;
	}
}

int32 AMove_2D::step() // 50% 확률구하기 이동용
{
	if (FMath::RandRange(0, 1))
	{
		return 1;
	}
		return 0;
}

float AMove_2D::distance(FVector2D a, FVector2D b) // 두 좌표 거리 구하기 
{
	return FMath::Sqrt((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
}

int32 AMove_2D::createEvent() // 50% 확률구하기 이벤트용
{
	if (FMath::RandRange(0, 1))
	{
		return 1;
	}
	return 0;
}
void AMove_2D::BeginPlay()
{
	Super::BeginPlay();

	int32 count = 0; // 이동 횟수
	evCnt = 0;
	totDist = 0;
	location = FVector2D(0, 0);

	UE_LOG(LogTemp, Error, TEXT("move start, Current Location(%.0f, %.0f)"), location.X, location.Y); // 시작 좌표 출력

	while (count < 10)
	{
		start = FVector2D(location.X, location.Y); // 이동 전 좌표
		
		move();

		end = FVector2D(location.X, location.Y); // 이동 후 좌표

		UE_LOG(LogTemp, Warning, TEXT("Current Location(%.0f, %.0f), Move Distance: %.3f"), location.X, location.Y, distance(start, end)); // 이동 후 좌표, 거리 출력

		totDist += distance(start, end); // 총 이동 거리 구하기

		if (createEvent() == 1) // 50% 확률로 이벤트 출력
		{
			UE_LOG(LogTemp, Error, TEXT("Event!"));
			evCnt++; // 이벤트 카운트 증가
		}
		count++;
	}
	UE_LOG(LogTemp, Error, TEXT("TOTAL EVENT : %d, TOTAL DISTANCE : %.3f"), evCnt, totDist); // 총 이벤트 발생 횟수, 이동 거리 출력
}

이벤트 발생과 출력, 실행마다 랜덤한 이동, 총 발생한 이벤트 횟수와 이동 거리 모두 잘 출력이 된다.