[UE5] Lena: Dev Diary #14 - 인벤토리 위젯 구현 및 HUD 크로스헤어 변경

ChangJin·2024년 7월 16일
0

Unreal Engine5

목록 보기
83/102
post-thumbnail

2024.07.16

깃허브!풀리퀘!
https://github.com/ChangJin-Lee/Project-Lena https://github.com/ChangJin-Lee/Project-Lena/pull/14

이번 포스팅에서는 인벤토리 위젯 구현과 HUD 크로스헤어 변경 작업을 다룹니다. 월드에서 떨어진 아이템을 위젯에 표시하고, 이를 클릭하여 인벤토리에 추가하는 기능과 함께, 새로운 크로스헤어 디자인을 HUD에 적용한 과정을 설명합니다.

진행상황

  • ✅ 인벤토리 위젯 구현
    • ✅ 위젯 디자인 및 레이아웃 설정
    • ✅ 아이템 클릭 및 인벤토리 추가 기능 구현
  • ✅ 아이템 상호작용 시스템
    • ✅ 월드 아이템과의 상호작용 구현
    • ✅ 상호작용 시 인벤토리 업데이트
  • ✅ HUD 크로스헤어 변경
    • ✅ 새로운 크로스헤어 디자인 적용
인벤토리 위젯 구성도

기존의 방식은 월드에서 아이템을 줍는 단순한 형태였습니다. 획득한 아이템을 볼 수 없었습니다. 이제는 월드에 떨어진 아이템을 위젯에 표시하고 이를 클릭하여 인벤토리에 추가하는 더 직관적이고 유연한 시스템을 구현했습니다. 시각적으로도 매우 잘 보입니다.

인벤토리 위젯 구현

인벤토리 위젯은 UMG를 사용하여 디자인되었습니다. 위젯은 아이템을 표시하고 클릭 이벤트를 처리합니다. 전체적인 코드는 저번 인벤토리 시스템 관리에서의 코드와 같습니다.

인벤토리 위젯
땅에 떨어져있는 아이템 주웠을 때 액터를 파괴하는 로직

PlayerController

이번 작업은 Widget과의 상호작용이 많았습니다. 시작부터 Character 쪽에 위젯 관련 로직을 구현할지, PlayerController 쪽에 위젯 관련 로직을 구현할지에 대해서 고민이 있었습니다. 구현하려는 인벤토리 위젯 시스템에서는 캐릭터 쪽에 로직을 구현하고 있는데, 위젯과 인풋이 적절하게 섞여있는 작업이라 PlayerController에 적용시켜보기로 했습니다.

마우스를 가져다 대면 아이템을 가져올 수 있는 기능, 주변에 있는 아이템을 볼 수 있는 기능 이 두가지를 PlayerController 쪽에 우선적으로 만들었습니다.

void AShooterPlayerController::HandlePickUpItem()
{
	FVector Start = PlayerCameraManager->GetCameraLocation();
	FVector End = PlayerCameraManager->GetCameraLocation() + (PlayerCameraManager->GetActorForwardVector() * 400.0f); // Adjust the length of the ray as needed

	FHitResult HitResult;
	FCollisionQueryParams Params;
	// Params.AddIgnoredActor(this);

	if (GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, Params))
	{
		AActor* HitActor = HitResult.GetActor();
		if(HitActor)
		{
			ABase_Item* Item = Cast<ABase_Item>(HitActor);
			if(Item)
			{
				if(Base_Character)
				{
					Base_Character->PickupItem(Item);
				}
			}
		}
	}
	// DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1.0f, 0, 1.0f);
	// DrawDebugSphere(GetWorld(), End, 25.0f, 50, FColor::Red, false, 1.0f, 0, 1.0f);
}

void AShooterPlayerController::CheckPickUpItemSweep()
{
	ACharacter* Character_ =  UGameplayStatics::GetPlayerCharacter(GetWorld(),0);
	FVector Start = Character_->GetActorLocation();
	FVector End = Character_->GetActorLocation();

	TArray<FHitResult> HitResults;
	FCollisionQueryParams Params;
	float Radius = 60.0f;

	if(GetWorld()->SweepMultiByChannel(HitResults, Start, End, FQuat::Identity, ECC_Visibility, FCollisionShape::MakeSphere(Radius), Params))
	{
		Base_Character->GroundItemsComponent->Items.Empty();
		
		for(FHitResult HitResult : HitResults )
		{
			AActor* HitActor = HitResult.GetActor();
			if(HitActor)
			{
				ABase_Item* Item = Cast<ABase_Item>(HitActor);
				if(Item)
				{
					if(Base_Character)
					{
						Base_Character->CheckGroundItem(Item);
					}
				}
			}
		}
	}
	// DrawDebugSphere(GetWorld(), Start, Radius, 10, FColor::Green, false, 5.0f, 0, 1.0f);
}

위젯 블루프린트로 메인 인벤토리 위젯에서 땅에 떨어져있는 아이템과 현재 인벤토리에 존재하는 아이템을 비교하고 추가, 삭제하는 로직을 만들었습니다.

InventoryMain Widget

인벤토리를 켜고 끌 때 마우스와 캐릭터의 이동을 잠그는 방법은 bShowMouseCurSor, SetIgnoreLookInput, SetIgnoreMoveInput, SetInputMode 을 사용했습니다.

결론

이번 작업을 통해 인벤토리 위젯을 구현했습니다. 월드에 떨어진 아이템을 위젯에 표시하고 이를 클릭하여 인벤토리에 추가하는 기능을 구현했습니다. 그리고 새로운 크로스헤어 디자인을 적용했습니다

참고 자료

profile
Unreal Engine 클라이언트 개발자

0개의 댓글