게임 개발 (언리얼 엔진)

UE4 생존게임 제작 - 13 (아이템 제작창 제작)

언린이 2020. 11. 13. 15:03

1. 아이템 제작창 UMG 생성

 

아이템 제작창 또한 인벤토리처럼 List View를 이용하여 제작하였습니다.

그래서 UMG를 제작하는 과정은 생략하도록 하겠습니다.

 

 

2. 아이템 제작창 키 입력 추가

 

 

프로젝트 세팅에서 아이템 제작창을 열기 위한 키 입력을 추가하였습니다.

 

 

PlayerInputComponent->BindAction(TEXT("OpenRecipe"), EInputEvent::IE_Pressed, this, &APlayerSurvivor::OpenRecipe);

 

그 다음 플레이어의 입력을 감지하는 SetupPlayerInputComponent 함수에서 액션 매핑을 통해 실행될 함수를 등록해주었습니다.

 

 

// 제작창을 여는 함수
void APlayerSurvivor::OpenRecipe()
{
	if (Recipe->IsVisible())
		Recipe->VisibleInventory(ESlateVisibility::Collapsed);
	else
		Recipe->VisibleInventory(ESlateVisibility::Visible);
}

 

키 입력이 들어오면 제작창의 Visibility를 확인하여 상태 설정을 해주었습니다.

(제작창 상태: Collapsed = 화면에 안보임, Visible = 화면에 보임)

 

 

3. Recipe Item Data 제작

 

이 또한 Inventory Item Data와 똑같이 작업하였기 때문에 생략하겠습니다.

 

 

 

아이템 제작창의 모습입니다.

 

 

4. 아이템 제작 코드 작성

 

	// List의 항목 클릭시 실행될 델리게이트에 함수 등록
	List->OnItemDoubleClicked().AddUObject(this, &URecipe::ItemClick);

 

void URecipe::ItemClick(UObject* obj)
{
	// 클릭된 아이템을 가져온다
	URecipeItemData* pData = Cast<URecipeItemData>(obj);

	if (IsValid(pData))
	{
		// 아이템의 인덱스를 가져온다
		int32 ItemIndex = pData->GetItemIndex();

		// 플레이어의 함수를 호출하기 위해 컨트롤러를 가져온다
		ASurvivorController* SurvivorController = Cast<ASurvivorController>(GetWorld()->GetFirstPlayerController());

		if (IsValid(SurvivorController))
		{
			// 플레이어를 가져온다
			APlayerSurvivor* Survivor = Cast<APlayerSurvivor>(SurvivorController->GetCharacter());

			if (IsValid(Survivor))
			{
				// 아이템 제작에 대한 작업을 시행하는 함수 호출
				Survivor->MakeItem(ItemIndex);
			}
		}
	}
}

 

List의 항목 클릭시 실행될 델리게이트에 함수를 등록해주었습니다.

그리고 해당 함수에서 플레이어에 정의해둔 아이템 제작에 대한 작업을 시행하는 함수를 호출하였습니다.

함수의 인자로는 어떤 아이템인지 알아야 하기 때문에 ItemIndex를 넘겨주었습니다.

 

 

// 제작창 항목 클릭시 실행될 함수
void APlayerSurvivor::MakeItem(int32 Index)
{
	// 구운 고기
	if (Index == 1)
	{
		UInventoryItemData* RawMeat = Cast<UInventoryItemData>(List->GetItemAt(0));
		UInventoryItemData* Branch = Cast<UInventoryItemData>(List->GetItemAt(4));
		UInventoryItemData* GrilledMeat = Cast<UInventoryItemData>(List->GetItemAt(1));

		if (RawMeat->GetItemCount() >= 1 && Branch->GetItemCount() >= 2)
		{
			GrilledMeat->SetItemCount(GrilledMeat->GetItemCount() + 1);
			RawMeat->SetItemCount(RawMeat->GetItemCount() - 1);
			Branch->SetItemCount(Branch->GetItemCount() - 2);
		}
	}
	// 화살
	else if (Index == 7)
	{
		UInventoryItemData* ZebraBone = Cast<UInventoryItemData>(List->GetItemAt(3));
		UInventoryItemData* Arrow = Cast<UInventoryItemData>(List->GetItemAt(7));

		// 가질 수 있는 화살 개수보다 적을 시 화살 제작 가능
		if (SurvivorState.iArrowNumMax > Arrow->GetItemCount())
		{
			if (ZebraBone->GetItemCount() >= 3)
			{
				Arrow->SetItemCount(Arrow->GetItemCount() + 1);
				ZebraBone->SetItemCount(ZebraBone->GetItemCount() - 3);
			}
		}
	}
	// 가죽
	else if (Index == 8)
	{
		UInventoryItemData* DeerLeather = Cast<UInventoryItemData>(List->GetItemAt(2));
		UInventoryItemData* Leather = Cast<UInventoryItemData>(List->GetItemAt(8));

		if (DeerLeather->GetItemCount() >= 5)
		{
			Leather->SetItemCount(Leather->GetItemCount() + 1);
			DeerLeather->SetItemCount(DeerLeather->GetItemCount() - 5);
		}
	}
	// 강화 가죽
	else if (Index == 9)
	{
		UInventoryItemData* LionLeather = Cast<UInventoryItemData>(List->GetItemAt(5));
		UInventoryItemData* HardLeather = Cast<UInventoryItemData>(List->GetItemAt(9));

		if (LionLeather->GetItemCount() >= 5)
		{
			HardLeather->SetItemCount(HardLeather->GetItemCount() + 1);
			LionLeather->SetItemCount(LionLeather->GetItemCount() - 5);
		}
	}
	// 햇빛 가리개
	else if (Index == 10)
	{
		UInventoryItemData* Sunscreen = Cast<UInventoryItemData>(List->GetItemAt(10));

		if (Sunscreen->GetItemCount() == 0)
		{
			UInventoryItemData* Leather = Cast<UInventoryItemData>(List->GetItemAt(8));

			if (Leather->GetItemCount() >= 3)
			{
				Sunscreen->SetItemCount(1);
				Leather->SetItemCount(Leather->GetItemCount() - 3);

				// 수분 게이지 줄어드는 속도 감소
				MoistureMax *= 2.f;
			}
		}
	}
	// 망토
	else if (Index == 11)
	{
		UInventoryItemData* Cloak = Cast<UInventoryItemData>(List->GetItemAt(11));

		if (Cloak->GetItemCount() == 0)
		{
			UInventoryItemData* HardLeather = Cast<UInventoryItemData>(List->GetItemAt(9));

			if (HardLeather->GetItemCount() >= 3)
			{
				Cloak->SetItemCount(1);
				HardLeather->SetItemCount(HardLeather->GetItemCount() - 3);

				// 수분 게이지 줄어드는 속도 감소
				MoistureMax *= 2.f;
			}
		}
	}
	// 화살통
	else if (Index == 12)
	{
		UInventoryItemData* Leather = Cast<UInventoryItemData>(List->GetItemAt(8));
		UInventoryItemData* HardLeather = Cast<UInventoryItemData>(List->GetItemAt(9));
		UInventoryItemData* ArrowBag = Cast<UInventoryItemData>(List->GetItemAt(12));

		if (Leather->GetItemCount() >= 3 && HardLeather->GetItemCount() >= 2)
		{
			ArrowBag->SetItemCount(ArrowBag->GetItemCount() + 1);
			Leather->SetItemCount(Leather->GetItemCount() - 3);
			HardLeather->SetItemCount(HardLeather->GetItemCount() - 2);
			
			SurvivorState.iArrowNumMax += 10;
		}
	}
	// Armor Up
	else if (Index == 13)
	{
		// 방어력이 30을 넘으면 더이상 아이템을 못만든다
		if (SurvivorState.fArmor < 20.f)
		{
			UInventoryItemData* HardLeather = Cast<UInventoryItemData>(List->GetItemAt(9));
			UInventoryItemData* ArmorUp = Cast<UInventoryItemData>(List->GetItemAt(13));

			if (HardLeather->GetItemCount() >= 5)
			{
				ArmorUp->SetItemCount(ArmorUp->GetItemCount() + 1);
				HardLeather->SetItemCount(HardLeather->GetItemCount() - 5);
			}
		}
	}
	// Attack Up
	else if (Index == 14)
	{
		// 공격력이 30을 넘으면 더이상 아이템을 못만든다
		if (SurvivorState.fAttack < 30.f)
		{
			UInventoryItemData* Horn = Cast<UInventoryItemData>(List->GetItemAt(6));
			UInventoryItemData* AttackUp = Cast<UInventoryItemData>(List->GetItemAt(14));

			if (Horn->GetItemCount() >= 3)
			{
				AttackUp->SetItemCount(AttackUp->GetItemCount() + 1);
				Horn->SetItemCount(Horn->GetItemCount() - 3);
			}
		}
	}

	// List 업데이트
	List->RegenerateAllEntries();
}

 

각각 어떤 아이템이냐에 따라서 제작에 대한 제약사항이 다르기 때문에 if - else if 문을 사용하여 아이템 제작에 따른 인벤토리를 업데이트해주었습니다.

 

 

 

Arrow를 만드는데, Zebra Bone이 3개가 필요합니다.

한번 Arrow를 만들어 보도록 하겠습니다.

 

 

 

아이템 제작창의 Arrow를 3번을 클릭하였습니다.

인벤토리에서 Zebra Bone의 개수는 9개가 감소하고 Arrow의 개수는 3개가 증가한 것을 확인할 수 있습니다.

 

 

다음에 해야할 일

 

트리거 제작