본문 바로가기

[UE4 지뢰찾기] 키 입력 처리하기

Kwonriver 2022. 12. 12.
728x90

 

키 입력을 처리하기 위한 Character를 만들었음.

사실 Pawn으로 만들어서 PlayerController를 붙여도 되긴하는데 Character에 이미 있는 Controller를 사용하기로 함

 

InputManageCharacter라는 이름으로 만든 이 액터는 플레이어의 입력만을 처리한다.

 

 

void MouseLeftClick(), void MouseRightClick()만 추가하였음

플레이어의 인풋 정보를 셋업할 void AInputManageCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 함수에다 입력 처리를 할 함수를 바인딩 해준다.

 

 

MouseLeftClick은 마우스 왼쪽 클릭으로 지뢰찾기의 타일을 클릭하여 뒤집는 기능을 한다.

MouseRightClick은 마우스 오른쪽 클릭으로 타일에 깃발을 심는 일을 한다.

 

void AInputManageCharacter::MouseLeftClick()
{
	APlayerController* playerController = UGameplayStatics::GetPlayerController(this, 0);
	if (playerController != nullptr)
	{
		FHitResult Hit;
		playerController->GetHitResultUnderCursor(ECC_Visibility, false, Hit);

		if (Hit.bBlockingHit == false)
			return;

		ATile* tile = Cast<ATile>(Hit.Actor);
		if (tile == nullptr)
		{
			UE_LOG(LogTemp, Warning, TEXT("Hit Actor is not tile"));
			return;
		}

		auto gameMode = Cast<AFindMineGameGameModeBase>(UGameplayStatics::GetGameMode(this));
		if (gameMode == nullptr)
		{
			UE_LOG(LogTemp, Warning, TEXT("GameMode cast fail"));
			return;
		}

		if (gameMode->GetMineGameState() == EMineGameState::GS_StepOnMine)
		{
			UE_LOG(LogTemp, Warning, TEXT("EMineGameState::GS_StepOnMine. Can not Click"));
			return;
		}

		ABoard* board = gameMode->GetBoardMap();
		if (board != nullptr)
		{
			auto tileState = board->CheckMineInUserTouchedTile(tile, false);
			if (tileState == EMineGameState::GS_StepOnMine)
			{
				// 게임 종료
				UE_LOG(LogTemp, Warning, TEXT("Click Mine, Game Over"));
				gameMode->SetMineGameState(EMineGameState::GS_StepOnMine);
			}
		}
	}
}

 

void AInputManageCharacter::MouseRightClick()
{
	APlayerController* playerController = UGameplayStatics::GetPlayerController(this, 0);
	if (playerController != nullptr)
	{
		FHitResult Hit;
		playerController->GetHitResultUnderCursor(ECC_Visibility, false, Hit);

		if (Hit.bBlockingHit == false)
			return;

		ATile* tile = Cast<ATile>(Hit.Actor);
		if (tile == nullptr)
		{
			UE_LOG(LogTemp, Warning, TEXT("Hit Actor is not tile"));
			return;
		}

		auto gameMode = Cast<AFindMineGameGameModeBase>(UGameplayStatics::GetGameMode(this));
		if (gameMode == nullptr)
		{
			UE_LOG(LogTemp, Warning, TEXT("GameMode cast fail"));
			return;
		}

		if (gameMode->GetMineGameState() == EMineGameState::GS_StepOnMine)
		{
			UE_LOG(LogTemp, Warning, TEXT("EMineGameState::GS_StepOnMine. Can not Click"));
			return;
		}

		ABoard* board = gameMode->GetBoardMap();
		if (board != nullptr)
		{
			auto tileState = board->CheckMineInUserTouchedTile(tile, true);
			if (tileState == EMineGameState::GS_StepOnMine)
			{
				// 게임 종료
				UE_LOG(LogTemp, Warning, TEXT("Click Mine, Game Over"));
				gameMode->SetMineGameState(EMineGameState::GS_StepOnMine);
			}
			else if (tileState == EMineGameState::GS_FoundAllMine)
			{
				// 게임 클리어!
				UE_LOG(LogTemp, Warning, TEXT("Game Clear!!"));
				gameMode->SetMineGameState(EMineGameState::GS_FoundAllMine);
			}
		}
	}
}

 

이 두 함수의 전반적인 틀은 커서 아래로 선을 쏜 뒤 처음 만난 객체를 FHitResult 구조체에 담아 반환한다.

해당 FHitResult 구조체의 액터를 타일로 타입캐스팅하고 정상적으로 캐스팅되었다면 GameMode의 맵을 가져와 타일 체크를 진행한다.

 

이 때 우클릭했는데 지뢰였다면 게임을 종료시킨다. 좌클릭했는데 모든 지뢰를 찾은 상태라면 게임을 승리한 상태로 넘어간다.

 

728x90