diff --git a/Content/Characters/NonPlayer/testNPC2_JS.uasset b/Content/Characters/NonPlayer/testNPC2_JS.uasset index 16f60ab8..9c3863e9 100644 Binary files a/Content/Characters/NonPlayer/testNPC2_JS.uasset and b/Content/Characters/NonPlayer/testNPC2_JS.uasset differ diff --git a/Content/Characters/Player/BP_MJNewPlayerCharacter.uasset b/Content/Characters/Player/BP_MJNewPlayerCharacter.uasset index db52e50b..6c205b7c 100644 Binary files a/Content/Characters/Player/BP_MJNewPlayerCharacter.uasset and b/Content/Characters/Player/BP_MJNewPlayerCharacter.uasset differ diff --git a/Content/Core/Controller/BP_MJPlayerController.uasset b/Content/Core/Controller/BP_MJPlayerController.uasset index 8a35f2a7..14d9c5e4 100644 Binary files a/Content/Core/Controller/BP_MJPlayerController.uasset and b/Content/Core/Controller/BP_MJPlayerController.uasset differ diff --git a/Content/DataTable/Dialogue/DT_Script_Sister.uasset b/Content/DataTable/Dialogue/DT_Script_Sister.uasset new file mode 100644 index 00000000..447bb414 Binary files /dev/null and b/Content/DataTable/Dialogue/DT_Script_Sister.uasset differ diff --git a/Content/DataTable/Dialogue/MJDataTableTest.uasset b/Content/DataTable/Dialogue/MJDataTableTest.uasset index 6c3ea2b3..a4fb2704 100644 Binary files a/Content/DataTable/Dialogue/MJDataTableTest.uasset and b/Content/DataTable/Dialogue/MJDataTableTest.uasset differ diff --git a/Content/DataTable/Dialogue/MJDataTableTest2.uasset b/Content/DataTable/Dialogue/MJDataTableTest2.uasset index 65b401d2..cae66010 100644 Binary files a/Content/DataTable/Dialogue/MJDataTableTest2.uasset and b/Content/DataTable/Dialogue/MJDataTableTest2.uasset differ diff --git a/Content/Input/IMC_Default.uasset b/Content/Input/IMC_Default.uasset index 94f65396..9e634e79 100644 Binary files a/Content/Input/IMC_Default.uasset and b/Content/Input/IMC_Default.uasset differ diff --git a/Content/Input/IMC_Dialogue.uasset b/Content/Input/IMC_Dialogue.uasset index e56b0df8..5f78e74c 100644 Binary files a/Content/Input/IMC_Dialogue.uasset and b/Content/Input/IMC_Dialogue.uasset differ diff --git a/Content/Maps/Tutorial_StartStory.umap b/Content/Maps/Tutorial_StartStory.umap new file mode 100644 index 00000000..5693855f Binary files /dev/null and b/Content/Maps/Tutorial_StartStory.umap differ diff --git a/Content/TG/TestWBP/WBP_MainMenu.uasset b/Content/TG/TestWBP/WBP_MainMenu.uasset index c1e917e7..0bc5bae9 100644 Binary files a/Content/TG/TestWBP/WBP_MainMenu.uasset and b/Content/TG/TestWBP/WBP_MainMenu.uasset differ diff --git a/Content/UI/Texture/Campanue.png b/Content/UI/Texture/Campanue.png new file mode 100644 index 00000000..8363c8db Binary files /dev/null and b/Content/UI/Texture/Campanue.png differ diff --git a/Content/UI/Texture/Campanue.uasset b/Content/UI/Texture/Campanue.uasset new file mode 100644 index 00000000..fc55cf17 Binary files /dev/null and b/Content/UI/Texture/Campanue.uasset differ diff --git a/Content/UI/Texture/NPCMug1.png b/Content/UI/Texture/NPCMug1.png new file mode 100644 index 00000000..8639d7e4 Binary files /dev/null and b/Content/UI/Texture/NPCMug1.png differ diff --git a/Content/UI/Texture/NPCMug1.uasset b/Content/UI/Texture/NPCMug1.uasset new file mode 100644 index 00000000..9b869796 Binary files /dev/null and b/Content/UI/Texture/NPCMug1.uasset differ diff --git a/Content/UI/Texture/PlayerMug2.png b/Content/UI/Texture/PlayerMug2.png new file mode 100644 index 00000000..bd6bab74 Binary files /dev/null and b/Content/UI/Texture/PlayerMug2.png differ diff --git a/Content/UI/Texture/PlayerMug2.uasset b/Content/UI/Texture/PlayerMug2.uasset new file mode 100644 index 00000000..a6c4dfd9 Binary files /dev/null and b/Content/UI/Texture/PlayerMug2.uasset differ diff --git a/Content/UI/Texture/PlayerMug3.png b/Content/UI/Texture/PlayerMug3.png new file mode 100644 index 00000000..c0f47c4c Binary files /dev/null and b/Content/UI/Texture/PlayerMug3.png differ diff --git a/Content/UI/Texture/PlayerMug3.uasset b/Content/UI/Texture/PlayerMug3.uasset new file mode 100644 index 00000000..baac93f4 Binary files /dev/null and b/Content/UI/Texture/PlayerMug3.uasset differ diff --git a/Content/UI/Texture/PlayerMug4.png b/Content/UI/Texture/PlayerMug4.png new file mode 100644 index 00000000..643708e0 Binary files /dev/null and b/Content/UI/Texture/PlayerMug4.png differ diff --git a/Content/UI/Texture/PlayerMug4.uasset b/Content/UI/Texture/PlayerMug4.uasset new file mode 100644 index 00000000..d9af0efd Binary files /dev/null and b/Content/UI/Texture/PlayerMug4.uasset differ diff --git a/Content/UI/WBP/Dialogue/BP_MJDialogueWidget.uasset b/Content/UI/WBP/Dialogue/BP_MJDialogueWidget.uasset index a697e083..49db181d 100644 Binary files a/Content/UI/WBP/Dialogue/BP_MJDialogueWidget.uasset and b/Content/UI/WBP/Dialogue/BP_MJDialogueWidget.uasset differ diff --git a/Content/UI/WBP/HUD/WBP_HUD.uasset b/Content/UI/WBP/HUD/WBP_HUD.uasset index a1a44f3e..2d7e4972 100644 Binary files a/Content/UI/WBP/HUD/WBP_HUD.uasset and b/Content/UI/WBP/HUD/WBP_HUD.uasset differ diff --git a/Content/UI/WBP/Tutorial/Actor/AttackInstructionCollision.uasset b/Content/UI/WBP/Tutorial/Actor/AttackInstructionCollision.uasset new file mode 100644 index 00000000..5411f3f6 Binary files /dev/null and b/Content/UI/WBP/Tutorial/Actor/AttackInstructionCollision.uasset differ diff --git a/Content/UI/WBP/Tutorial/Actor/ChargeSkillInstructionCollision.uasset b/Content/UI/WBP/Tutorial/Actor/ChargeSkillInstructionCollision.uasset new file mode 100644 index 00000000..f845b656 Binary files /dev/null and b/Content/UI/WBP/Tutorial/Actor/ChargeSkillInstructionCollision.uasset differ diff --git a/Content/UI/WBP/Tutorial/Actor/InstantSkillInstructionCollision.uasset b/Content/UI/WBP/Tutorial/Actor/InstantSkillInstructionCollision.uasset new file mode 100644 index 00000000..0be3fe91 Binary files /dev/null and b/Content/UI/WBP/Tutorial/Actor/InstantSkillInstructionCollision.uasset differ diff --git a/Content/UI/WBP/Tutorial/AttackInstructionCollision.uasset b/Content/UI/WBP/Tutorial/AttackInstructionCollision.uasset new file mode 100644 index 00000000..032e0985 Binary files /dev/null and b/Content/UI/WBP/Tutorial/AttackInstructionCollision.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_Detection.uasset b/Content/UI/WBP/Tutorial/WBP_Detection.uasset new file mode 100644 index 00000000..f28fc7df Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_Detection.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_Mouse.uasset b/Content/UI/WBP/Tutorial/WBP_Mouse.uasset new file mode 100644 index 00000000..639224c9 Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_Mouse.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_RightMouse.uasset b/Content/UI/WBP/Tutorial/WBP_RightMouse.uasset new file mode 100644 index 00000000..3abc62cf Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_RightMouse.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_RightMousePress.uasset b/Content/UI/WBP/Tutorial/WBP_RightMousePress.uasset new file mode 100644 index 00000000..7ca87d05 Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_RightMousePress.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_Shift.uasset b/Content/UI/WBP/Tutorial/WBP_Shift.uasset new file mode 100644 index 00000000..8cda9a3d Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_Shift.uasset differ diff --git a/Content/UI/WBP/Tutorial/WBP_TutorialInstruction.uasset b/Content/UI/WBP/Tutorial/WBP_TutorialInstruction.uasset new file mode 100644 index 00000000..0f5bf263 Binary files /dev/null and b/Content/UI/WBP/Tutorial/WBP_TutorialInstruction.uasset differ diff --git a/Source/ProjectMJ/Character/MJPlayerCharacter.cpp b/Source/ProjectMJ/Character/MJPlayerCharacter.cpp index 64c6352b..1ddc9165 100644 --- a/Source/ProjectMJ/Character/MJPlayerCharacter.cpp +++ b/Source/ProjectMJ/Character/MJPlayerCharacter.cpp @@ -19,6 +19,7 @@ #include "Component/MJPlayerStatComponent.h" #include "Perception/AISense_Damage.h" #include "Perception/AISense_Hearing.h" +#include "UI/Tutorial/MJTutorialStartDialogueComponent.h" class UMJSaveGameSubsystem; @@ -79,6 +80,7 @@ AMJPlayerCharacter::AMJPlayerCharacter() UITrigger->SetHiddenInGame(true); InventoryComponent = CreateDefaultSubobject(TEXT("InventoryComponent")); + TutorialDialogueComp = CreateDefaultSubobject(TEXT("TutorialDialogueComponent")); // Skill Component SkillComponent = CreateDefaultSubobject(TEXT("SkillComponent")); // Stat Component diff --git a/Source/ProjectMJ/Character/MJPlayerCharacter.h b/Source/ProjectMJ/Character/MJPlayerCharacter.h index e7f993cd..22f6d1b4 100644 --- a/Source/ProjectMJ/Character/MJPlayerCharacter.h +++ b/Source/ProjectMJ/Character/MJPlayerCharacter.h @@ -9,6 +9,7 @@ #include "UI/Inventory/MJInventoryInterface.h" #include "MJPlayerCharacter.generated.h" +class UMJTutorialStartDialogueComponent; class UMJPlayerEffectComponent; class UMJPlayerStatComponent; class UMJPlayerSkillComponent; @@ -66,6 +67,9 @@ class PROJECTMJ_API AMJPlayerCharacter : public AMJCharacterBase, public IMJInve UPROPERTY() TObjectPtr UITarget; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Tutorial") + TObjectPtr TutorialDialogueComp; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Inventory") TObjectPtr InventoryComponent; diff --git a/Source/ProjectMJ/Controller/MJPlayerController.cpp b/Source/ProjectMJ/Controller/MJPlayerController.cpp index bf6e3fe2..2cbb4ffb 100644 --- a/Source/ProjectMJ/Controller/MJPlayerController.cpp +++ b/Source/ProjectMJ/Controller/MJPlayerController.cpp @@ -21,6 +21,7 @@ #include "DataTable/MJSkillDataRow.h" #include "UI/Inventory/MJInventoryComponent.h" #include "Item/MJItemBase.h" +#include "Kismet/GameplayStatics.h" #include "TG/UI/MJGameFlowHUDWidget.h" #include "UI/MJHUDWidget.h" #include "UI/Component/MJInteractComponent.h" @@ -32,6 +33,8 @@ #include "UI/Store/MJStoreComponent.h" #include "UI/Store/MJStoreWidget.h" #include "UI/Skill/MJSkillSlotWidget.h" +#include "UI/Tutorial/MJTutorialCollision.h" +#include "UI/Tutorial/MJTutorialStartDialogueComponent.h" // TODO: Input 관련한 로직들 Component로 따로 빼기 - 동민 - @@ -120,8 +123,20 @@ void AMJPlayerController::BeginPlay() UIManager->GetHUDWidget()->GetSkillWidget()->GetSkillSlots()[i]->OnClickedEquipButton.AddDynamic(this,&AMJPlayerController::UpdateEquipedSkillWidget); UIManager->GetHUDWidget()->GetSkillWidget()->GetSkillSlots()[i]->GetEquipButton()->OnClicked.AddDynamic(this,&ThisClass::GetOwnedSkill); } - - + + const FString CurrentLevel = UGameplayStatics::GetCurrentLevelName(this, true); + if (CurrentLevel.Equals(TEXT("Tutorial_StartStory"))) + { + ChangeToIMCDialogue(); + bIsTutorialMode = true; + UMJTutorialStartDialogueComponent* TutorialStartDialogue = MJChar->FindComponentByClass(); + if (!TutorialStartDialogue) + { + return; + } + TutorialStartDialogue->FloatLine(); + TutorialStartDialogue->OnTutorialStartDialogueEnd.AddDynamic(this,&ThisClass::TutorialDialogueEnd); + } } void AMJPlayerController::SetupInputComponent() @@ -143,6 +158,8 @@ void AMJPlayerController::SetupInputComponent() //Dialogue Input MJInputComponent->BindAction(ChangeIMCAction, ETriggerEvent::Triggered, this, &ThisClass::StartDialogue); MJInputComponent->BindAction(NextDialogueAction, ETriggerEvent::Triggered, this, &ThisClass::ProceedDialogue); + + MJInputComponent->BindAction(ShowBacklogAction, ETriggerEvent::Triggered, this, &ThisClass::ShowBacklog); // UI Input @@ -420,8 +437,7 @@ void AMJPlayerController::StartDialogue()// x키를 눌렀을 때 실행되는 if (!MyChar) return; if (UMJInteractComponent* InteractComp = MyChar->GetUITarget()->FindComponentByClass()) - { - + { InteractComp->StartInteraction(); switch (InteractComp->CurrentType) { @@ -438,7 +454,12 @@ void AMJPlayerController::StartDialogue()// x키를 눌렀을 때 실행되는 default: break; } - } + } + + if (bIsTutorialMode) + { + UIManager->GetHUDWidget()->SetInstructionWidgetVisibility(); + } } void AMJPlayerController::ChangeToIMCDialogue() @@ -467,23 +488,42 @@ void AMJPlayerController::ProceedDialogue() { return; } - if (!MyChar->GetUITarget()) + if (MyChar->GetUITarget()) { - return; + UMJInteractComponent* InteractComp = MyChar->GetUITarget()->FindComponentByClass(); + if (InteractComp) + { + InteractComp->ProceedInteraction(); + return; + } } - - UMJInteractComponent* InteractComp = MyChar->GetUITarget()->FindComponentByClass(); - if (!InteractComp) + if (bIsTutorialMode) { - return; + UMJTutorialStartDialogueComponent* TutorialStartDialogue = MyChar->FindComponentByClass(); + TutorialStartDialogue->ProceedStory(); } - InteractComp->ProceedInteraction(); } -void AMJPlayerController::SetDialogueVisibility() +void AMJPlayerController::DialogueEnd() { ChangeToIMCDefault(); UIManager->SetDialogueVisibility(); + if (bIsTutorialMode) + { + UIManager->GetHUDWidget()->SetMouseVisibility(); + UIManager->GetHUDWidget()->SetInstructionWidgetVisibility(); + UIManager->GetHUDWidget()->ShowShift(); + UIManager->GetHUDWidget()->SetInstructionText("Move right and defeat the monster. Hold Shift and left-click to execute a basic attack."); + } +} + +void AMJPlayerController::TutorialDialogueEnd() // Tutorial 시작 다이어로그가 끝나면 +{ + ChangeToIMCDefault(); + UIManager->SetDialogueVisibility(); + UIManager->GetHUDWidget()->SetLeftMouse(); + UIManager->GetHUDWidget()->SetInstructionWidgetVisibility(); + UIManager->GetHUDWidget()->SetInstructionText("Click the left mouse button to move the map. Move to your sister."); } void AMJPlayerController::ShowStore() @@ -547,7 +587,6 @@ void AMJPlayerController::GetOwnedSkill() AMJPlayerCharacter* MJChar = Cast(GetPawn()); if (UMJPlayerSkillComponent* SkillComponent = MJChar->FindComponentByClass()) { - SkillComponent->EquipSkill(TempTag); UE_LOG(LogTemp,Error,TEXT("AMJPlayerController::GetOwnedSkill, %s"),*TempTag.ToString()); } @@ -564,8 +603,8 @@ void AMJPlayerController::OnTriggeredIn(UPrimitiveComponent* Overlapped, AActor* IsInteracted = true; InteractComp->OnBeginInteract(); - InteractComp->OndialogueEnd.RemoveDynamic(this, &AMJPlayerController::SetDialogueVisibility); - InteractComp->OndialogueEnd.AddDynamic(this, &AMJPlayerController::SetDialogueVisibility); + InteractComp->OndialogueEnd.RemoveDynamic(this, &AMJPlayerController::DialogueEnd); + InteractComp->OndialogueEnd.AddDynamic(this, &AMJPlayerController::DialogueEnd); InteractComp->OnstoreOpen.RemoveDynamic(this, &AMJPlayerController::ShowStore); InteractComp->OnstoreOpen.AddDynamic(this, &AMJPlayerController::ShowStore); @@ -581,6 +620,37 @@ void AMJPlayerController::OnTriggeredIn(UPrimitiveComponent* Overlapped, AActor* InteractComp->GetStoreComponent()->SetItemData(MJChar->GetInventoryComponent()->GetItemTags(),MJChar->GetInventoryComponent()->GetItemTags().Num(),MJChar->GetInventoryComponent()); } } + + if (bIsTutorialMode && !UIManager->GetbHasRun()) + { + UIManager->GetHUDWidget()->SetMouseVisibility(); // OFF + UIManager->GetHUDWidget()->SetInstructionText("Interaction is possible with F key. Press F key to talk with your sister."); + UIManager->SetbHasRun(true); + } + } + + if (AMJTutorialCollision* TutorialCollision = Cast(Other)) + { + // if (TutorialCollision->GetCollisionType() == ECollisionType::AttackTutorial) + // { + // UIManager->GetHUDWidget()->ShowShift(); + // UIManager->GetHUDWidget()->SetInstructionText(TutorialCollision->GetInstructionText()); + // } + + if (TutorialCollision->GetCollisionType() == ECollisionType::InstantSkillTutorial) + { + UIManager->GetHUDWidget()->HideShift(); + UIManager->GetHUDWidget()->SetRightMouse(); + UIManager->GetHUDWidget()->SetInstructionText(TutorialCollision->GetInstructionText()); + TutorialCollision->Hide(); + } + + if (TutorialCollision->GetCollisionType() == ECollisionType::ChargeSkillTutorial) + { + UIManager->GetHUDWidget()->SetRightPressMouse(); + UIManager->GetHUDWidget()->SetInstructionText(TutorialCollision->GetInstructionText()); + TutorialCollision->Hide(); + } } } } diff --git a/Source/ProjectMJ/Controller/MJPlayerController.h b/Source/ProjectMJ/Controller/MJPlayerController.h index afb4225f..d62dd3a8 100644 --- a/Source/ProjectMJ/Controller/MJPlayerController.h +++ b/Source/ProjectMJ/Controller/MJPlayerController.h @@ -77,6 +77,8 @@ class PROJECTMJ_API AMJPlayerController : public APlayerController TObjectPtr ShiftAction; #pragma region UIPart private: + bool bIsTutorialMode = false; + bool IsInteracted = false; FGameplayTag PurchaseItemTag; int32 ItemPrice; @@ -125,7 +127,11 @@ class PROJECTMJ_API AMJPlayerController : public APlayerController void ProceedDialogue(); UFUNCTION() - void SetDialogueVisibility(); + void DialogueEnd(); + + UFUNCTION() + void TutorialDialogueEnd(); + // Store UFUNCTION() void ShowStore(); diff --git a/Source/ProjectMJ/Dialogue/MJBacklogWidget.cpp b/Source/ProjectMJ/Dialogue/MJBacklogWidget.cpp index 3754eb2b..52b31211 100644 --- a/Source/ProjectMJ/Dialogue/MJBacklogWidget.cpp +++ b/Source/ProjectMJ/Dialogue/MJBacklogWidget.cpp @@ -8,34 +8,33 @@ #include "Dialogue/MJDialogueRow.h" #include "Fonts/SlateFontInfo.h" -void UMJBacklogWidget::AddLine(const FMJDialogueRow& Row) // 함수명 수정하기 > AddLine으로 +void UMJBacklogWidget::AddLine(const FMJDialogueRow& Row) { if (!BacklogScrollBox) return; FString Line = Row.Speaker + TEXT(" : ") + Row.Script; - UTextBlock* NewTextBlock = NewObject(BacklogScrollBox); + NewTextBlock = NewObject(BacklogScrollBox); if (NewTextBlock) { - // 폰트 변경 + // 폰트 변경 // 런타임 내에서 텍스트블록이 형성되므로 에디터 상에서 변경이 어려울 듯 하여 FSlateFontInfo FontInfo; - FontInfo.FontObject = LoadObject(nullptr, TEXT("/Game/UI/Font/CookieRun_Regular_Font.CookieRun_Regular_Font")); + FontInfo.FontObject = LoadObject(nullptr, TEXT("/Game/UI/Font/CookieRun_Regular_Font.CookieRun_Regular_Font")); // FontInfo.Size = 15; NewTextBlock->SetFont(FontInfo); + // 텍스트 색 변경 + FSlateColor SetColor = FSlateColor(FLinearColor::White); + NewTextBlock->SetColorAndOpacity(SetColor); + + // 대사 행 간격 + if (UScrollBoxSlot* ScrollSlot = Cast(NewTextBlock->Slot)) + { + ScrollSlot->SetPadding(FMargin(20, 5, 20, 5)); + } NewTextBlock->SetText(FText::FromString(Line)); BacklogScrollBox->AddChild(NewTextBlock); - - // 텍스트 색 변경 - FSlateColor SetColor = FSlateColor(FLinearColor::White); - NewTextBlock->SetColorAndOpacity(SetColor); - - // 대사 행 간격 - if (UScrollBoxSlot* ScrollSlot = Cast(NewTextBlock->Slot)) - { - ScrollSlot->SetPadding(FMargin(20, 5, 20, 5)); - } } } diff --git a/Source/ProjectMJ/Dialogue/MJBacklogWidget.h b/Source/ProjectMJ/Dialogue/MJBacklogWidget.h index cffa1675..4dea801c 100644 --- a/Source/ProjectMJ/Dialogue/MJBacklogWidget.h +++ b/Source/ProjectMJ/Dialogue/MJBacklogWidget.h @@ -6,6 +6,7 @@ #include "Blueprint/UserWidget.h" #include "MJBacklogWidget.generated.h" + /* * Class Description: Backlog를 띄우는 위젯 클래스 * Author: 이지수 @@ -13,6 +14,9 @@ * Last Modified By: 이지수 * Last Modified Date: 2025.06.17 */ + +struct FMJDialogueRow; +class UTextBlock; class UScrollBox; UCLASS() class PROJECTMJ_API UMJBacklogWidget : public UUserWidget @@ -21,7 +25,10 @@ class PROJECTMJ_API UMJBacklogWidget : public UUserWidget protected: UPROPERTY(meta = (BindWidget)) - class UScrollBox* BacklogScrollBox; + TObjectPtr BacklogScrollBox; + + UPROPERTY() + TObjectPtr NewTextBlock; public: UFUNCTION() diff --git a/Source/ProjectMJ/Dialogue/MJDialogueComponent.cpp b/Source/ProjectMJ/Dialogue/MJDialogueComponent.cpp index b3a801fa..56fdcc1b 100644 --- a/Source/ProjectMJ/Dialogue/MJDialogueComponent.cpp +++ b/Source/ProjectMJ/Dialogue/MJDialogueComponent.cpp @@ -68,6 +68,8 @@ void UMJDialogueComponent::FloatLine() GetDialogueWidget()->SetTextBlock(GetCurrentRow()->Script, GetCurrentRow()->Speaker); GetDialogueWidget()->StartTyping(GetCurrentRow()->Script,0.05); GetDialogueWidget()->SetImageOpacity(GetCurrentRow()->Speaker); + GetDialogueWidget()->SetPlayerImage(GetCurrentRow()->PlayerMugImage); + GetDialogueWidget()->SetNPCImage(GetCurrentRow()->NPCMugImage); } const FMJDialogueRow* UMJDialogueComponent::GetCurrentRow() const diff --git a/Source/ProjectMJ/Dialogue/MJDialogueRow.h b/Source/ProjectMJ/Dialogue/MJDialogueRow.h index af4d7215..654ec3be 100644 --- a/Source/ProjectMJ/Dialogue/MJDialogueRow.h +++ b/Source/ProjectMJ/Dialogue/MJDialogueRow.h @@ -42,7 +42,12 @@ struct FMJDialogueRow : public FTableRowBase UPROPERTY(EditAnywhere, BlueprintReadWrite) FString ScriptForExit; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + UTexture2D* PlayerMugImage; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + UTexture2D* NPCMugImage; + UPROPERTY(EditAnywhere, BlueprintReadWrite) TArray Choices; // 선택지는 여러개니까 배열? }; diff --git a/Source/ProjectMJ/Dialogue/MJDialogueWidget.cpp b/Source/ProjectMJ/Dialogue/MJDialogueWidget.cpp index 2b10bbb0..12c98c30 100644 --- a/Source/ProjectMJ/Dialogue/MJDialogueWidget.cpp +++ b/Source/ProjectMJ/Dialogue/MJDialogueWidget.cpp @@ -5,6 +5,7 @@ #include "MJBacklogWidget.h" #include "Components/TextBlock.h" #include "Components/Image.h" +#include "Kismet/GameplayStatics.h" void UMJDialogueWidget::NativeConstruct() { @@ -30,6 +31,26 @@ void UMJDialogueWidget::SetTextBlock(const FString& InText,const FString& speake } } +void UMJDialogueWidget::SetNPCImage(UTexture2D* InNPCImage) +{ + if (NPCImage) + { + FSlateBrush Brush; + Brush.SetResourceObject(InNPCImage); + NPCImage->SetBrush(Brush); + } +} + +void UMJDialogueWidget::SetPlayerImage(UTexture2D* InPlayerImage) +{ + if (PlayerImage) + { + FSlateBrush Brush; + Brush.SetResourceObject(InPlayerImage); + PlayerImage->SetBrush(Brush); + } +} + void UMJDialogueWidget::StartTyping(const FString& InText, float TypingSpeed) { FullText = InText; @@ -86,7 +107,7 @@ void UMJDialogueWidget::SetImageOpacity(const FString& SpeakerName) if (!NPCImage) return; - if (SpeakerName == TEXT("Player")) + if (SpeakerName == TEXT("A la Mode")) { PlayerImage->SetOpacity(1.0f); NPCImage->SetOpacity(0.3f); diff --git a/Source/ProjectMJ/Dialogue/MJDialogueWidget.h b/Source/ProjectMJ/Dialogue/MJDialogueWidget.h index d30050e2..dfc28d9f 100644 --- a/Source/ProjectMJ/Dialogue/MJDialogueWidget.h +++ b/Source/ProjectMJ/Dialogue/MJDialogueWidget.h @@ -28,6 +28,8 @@ class PROJECTMJ_API UMJDialogueWidget : public UUserWidget virtual void NativeConstruct() override; void SetTextBlock(const FString& InText, const FString& Speaker); + void SetNPCImage(UTexture2D* InNPCImage); + void SetPlayerImage(UTexture2D* InPlayerImage); void ShowBacklog(); diff --git a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp index cc5f6a0a..b82a2c6f 100644 --- a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp +++ b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp @@ -6,10 +6,13 @@ #include "ProjectMJ.h" #include "BehaviorTree/BlackboardComponent.h" #include "BehaviorTree/BehaviorTreeComponent.h" +#include "MJ/Character/MJMonsterCharacter.h" #include "Perception/AIPerceptionComponent.h" #include "Perception/AISenseConfig_Sight.h" #include "Perception/AISenseConfig_Damage.h" #include "Perception/AISense_Hearing.h" +#include "UI/Component/MJDetectionWidgetComponent.h" +#include "UI/World/MJDetectionWidget.h" AMJMonsterAIControllerBase::AMJMonsterAIControllerBase() { @@ -195,6 +198,15 @@ void AMJMonsterAIControllerBase::HandleSight_Detected(AActor* Actor, FAIStimulus Blackboard->SetValueAsObject("Target", Actor); UE_LOG(LogMJ, Log, TEXT("시야로 감지")); Blackboard->SetValueAsBool("IsTargetVisible", true); + + // Jisoo + AMJMonsterCharacter* Monster = Cast(GetPawn()); + if (UMJDetectionWidget* DetectionWidget = Cast(Monster->GetDetectionComponent()->GetUserWidgetObject())) + { + Monster->GetDetectionComponent()->SetVisibility(true); + DetectionWidget->PlayAnim(); + } + } void AMJMonsterAIControllerBase::HandleDamage_Detected(AActor* Actor, FAIStimulus Stimulus) diff --git a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp index c5dd57d3..004cda6c 100644 --- a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp +++ b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp @@ -26,6 +26,7 @@ #include "MJ/DataAssetMJ/MJDropItemsDataAsset.h" #include "UI/Inventory/ItemDataRow.h" #include "UI/Bar/MJEnemyHPBar.h" +#include "UI/Component/MJDetectionWidgetComponent.h" #include "UI/Component/MJHealthBarComponent.h" AMJMonsterCharacter::AMJMonsterCharacter() @@ -58,6 +59,9 @@ AMJMonsterCharacter::AMJMonsterCharacter() HPBarComponent = CreateDefaultSubobject(TEXT("HPBarComponent")); HPBarComponent->SetupAttachment(GetRootComponent()); + DetectionComponent = CreateDefaultSubobject(TEXT("DetectionComponent")); + DetectionComponent->SetupAttachment(GetRootComponent()); + // Minjin: ID 설정 ID = ETeam_ID::MONSTER; } @@ -247,6 +251,7 @@ void AMJMonsterCharacter::OnDead(AActor* InEffectCauser) void AMJMonsterCharacter::OnDamage(float Magnitude, bool bIsCritical) { HPBarComponent->SetVisibility(true); + DetectionComponent->SetVisibility(true); FloatDamage(Magnitude, bIsCritical, EOwnerType::Monster); } diff --git a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h index dc31b7a9..ee76417e 100644 --- a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h +++ b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h @@ -10,6 +10,7 @@ #include "AbilitySystemComponent.h" #include "MJMonsterCharacter.generated.h" +class UMJDetectionWidgetComponent; class UMJEnemySkillComponent; class UMJDropItemsDataAsset; class UMJHealthBarComponent; @@ -46,7 +47,9 @@ class PROJECTMJ_API AMJMonsterCharacter : public AMJCharacterBase, public IGamep FGameplayTag GetAttackTag() {return AttackTag;} UMJEnemySkillComponent* GetSkillComponent() {return SkillComponent;} virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override; + UMJDetectionWidgetComponent* GetDetectionComponent(){return DetectionComponent;} + TObjectPtr GetAppearanceAnimation(){return AppearanceAnimation;} const EnemyTransferData& GetEnemyBequest(){return EnemyBequest;} @@ -96,8 +99,8 @@ class PROJECTMJ_API AMJMonsterCharacter : public AMJCharacterBase, public IGamep UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Widget, Meta = (AllowPrivateAccess = "true")) TObjectPtr HPBarComponent; - // UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Widget, Meta = (AllowPrivateAccess = "true")) - // TArray> DamageComponents; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Widget, Meta = (AllowPrivateAccess = "true")) + TObjectPtr DetectionComponent; int DamageIndex = 0; float OffSet = 0; diff --git a/Source/ProjectMJ/ProjectMJ.h b/Source/ProjectMJ/ProjectMJ.h index 3b9d9845..1782202a 100644 --- a/Source/ProjectMJ/ProjectMJ.h +++ b/Source/ProjectMJ/ProjectMJ.h @@ -11,6 +11,7 @@ // static MapName #define MAP_TOWN TEXT("TG_Town") #define MAP_MAINMENU TEXT("TG_MainMenu") +#define MAP_Tutorial TEXT("Tutorial_StartStory") // cpp 파일에 DEFINE_LOG_CATEGORY 선언 필요함 DECLARE_LOG_CATEGORY_EXTERN(LogMJ, Log, All); diff --git a/Source/ProjectMJ/TG/UI/MJMainMenuWidget.cpp b/Source/ProjectMJ/TG/UI/MJMainMenuWidget.cpp index 59aac231..19f7f7a4 100644 --- a/Source/ProjectMJ/TG/UI/MJMainMenuWidget.cpp +++ b/Source/ProjectMJ/TG/UI/MJMainMenuWidget.cpp @@ -5,6 +5,7 @@ #include "MJGameFlowPopUpMsgWidget.h" #include "MJSettingsWidget.h" +#include "ProjectMJ.h" #include "Components/Button.h" #include "Kismet/GameplayStatics.h" #include "Kismet/KismetSystemLibrary.h" @@ -16,6 +17,7 @@ void UMJMainMenuWidget::NativeConstruct() Super::NativeConstruct(); Button_NewGame->OnClicked.AddDynamic(this, &ThisClass::OnClicked_NewGame); + Button_Tutorial->OnClicked.AddDynamic(this, &ThisClass::OnClicked_Tutorial); Button_LoadGame->OnClicked.AddDynamic(this, &ThisClass::OnClicked_LoadGame); Button_Settings->OnClicked.AddDynamic(this, &ThisClass::OnClicked_Settings); Button_Quit->OnClicked.AddDynamic(this, &ThisClass::OnClicked_Quit); @@ -91,6 +93,12 @@ void UMJMainMenuWidget::OnClicked_NewGame() } } +void UMJMainMenuWidget::OnClicked_Tutorial() +{ + SetVisibility(ESlateVisibility::Hidden); + UGameplayStatics::OpenLevel(this,MAP_Tutorial); +} + void UMJMainMenuWidget::OnClicked_LoadGame() { SetVisibility(ESlateVisibility::Hidden); diff --git a/Source/ProjectMJ/TG/UI/MJMainMenuWidget.h b/Source/ProjectMJ/TG/UI/MJMainMenuWidget.h index 47802230..5f11ae9d 100644 --- a/Source/ProjectMJ/TG/UI/MJMainMenuWidget.h +++ b/Source/ProjectMJ/TG/UI/MJMainMenuWidget.h @@ -51,6 +51,9 @@ class PROJECTMJ_API UMJMainMenuWidget : public UUserWidget UPROPERTY(meta = (BindWidget)) TObjectPtr Button_NewGame; + UPROPERTY(meta = (BindWidget)) + TObjectPtr Button_Tutorial; + UPROPERTY(meta = (BindWidget)) TObjectPtr Button_LoadGame; @@ -62,6 +65,9 @@ class PROJECTMJ_API UMJMainMenuWidget : public UUserWidget UFUNCTION() void OnClicked_NewGame(); + + UFUNCTION() + void OnClicked_Tutorial(); UFUNCTION() void OnClicked_LoadGame(); diff --git a/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.cpp b/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.cpp new file mode 100644 index 00000000..4d4b728c --- /dev/null +++ b/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.cpp @@ -0,0 +1,26 @@ +// ThenOneDayStudio + + +#include "UI/Component/MJDetectionWidgetComponent.h" +#include "UI/World/MJDetectionWidget.h" + +UMJDetectionWidgetComponent::UMJDetectionWidgetComponent() +{ + static ConstructorHelpers::FClassFinder DetectionWidgetRef(TEXT("/Game/UI/WBP/Tutorial/WBP_Detection.WBP_Detection_C")); + + if (DetectionWidgetRef.Class) + { + SetWidgetClass(DetectionWidgetRef.Class); + } + + SetDetectionWidget(); +} + +void UMJDetectionWidgetComponent::SetDetectionWidget() +{ + SetRelativeLocation(FVector(0.0f, 0.0f, 200.0f)); + SetWidgetSpace(EWidgetSpace::Screen); + SetDrawSize(FVector2D(10.0f,10.0f)); + SetCollisionEnabled(ECollisionEnabled::NoCollision); + SetVisibility(false); +} diff --git a/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.h b/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.h new file mode 100644 index 00000000..94b3d5b6 --- /dev/null +++ b/Source/ProjectMJ/UI/Component/MJDetectionWidgetComponent.h @@ -0,0 +1,22 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "Components/WidgetComponent.h" +#include "MJDetectionWidgetComponent.generated.h" + +/** + * + */ +UCLASS() +class PROJECTMJ_API UMJDetectionWidgetComponent : public UWidgetComponent +{ + GENERATED_BODY() + +public: + UMJDetectionWidgetComponent(); + + void SetDetectionWidget(); + +}; diff --git a/Source/ProjectMJ/UI/MJHUDWidget.cpp b/Source/ProjectMJ/UI/MJHUDWidget.cpp index 7b7fafa4..dc1f16c0 100644 --- a/Source/ProjectMJ/UI/MJHUDWidget.cpp +++ b/Source/ProjectMJ/UI/MJHUDWidget.cpp @@ -9,13 +9,19 @@ #include "Bar/MJStaminaBar.h" #include "Bar/MJExperienceWidget.h" #include "Character/Component/MJPlayerStatComponent.h" +#include "Components/Border.h" #include "Components/Button.h" +#include "Components/WidgetInteractionComponent.h" +#include "Dialogue/MJBacklogWidget.h" #include "Dialogue/MJDialogueWidget.h" #include "World/MJStatWidget.h" #include "Inventory/MJInventoryWidget.h" +#include "Kismet/GameplayStatics.h" #include "Skill/MJSkillWidget.h" #include "Store/MJStoreWidget.h" #include "TG/UI/MJBossHpBarWidget.h" +#include "Tutorial/MJMouseWidget.h" +#include "Tutorial/MJTutorialInstruction.h" void UMJHUDWidget::NativeConstruct() { @@ -35,9 +41,27 @@ void UMJHUDWidget::NativeConstruct() Store->SetVisibility(ESlateVisibility::Hidden); } + const FString CurrentLevel = UGameplayStatics::GetCurrentLevelName(this, true); if (Dialogue) { - Dialogue->SetVisibility(ESlateVisibility::Hidden); + if (CurrentLevel.Equals(TEXT("Tutorial_StartStory"))) + { + Dialogue->SetVisibility(ESlateVisibility::Visible); + } + else + { + Dialogue->SetVisibility(ESlateVisibility::Hidden); + } + } + + if (Shift) + { + Shift->SetVisibility(ESlateVisibility::Hidden); + } + + if (Instruction) + { + Instruction->SetVisibility(ESlateVisibility::Hidden); } if (UIToggle) @@ -53,17 +77,18 @@ void UMJHUDWidget::NativeConstruct() } } +void UMJHUDWidget::ToggleWidget(UWidget* Widget) +{ + const bool bIsVisible = (Widget->GetVisibility() == ESlateVisibility::Visible); + Widget->SetVisibility(bIsVisible ? ESlateVisibility::Hidden : ESlateVisibility::Visible); +} + void UMJHUDWidget::BindAtrributesToChildren(UMJAbilitySystemComponent* ASC, UMJCharacterAttributeSet* AttributeSet, UMJPlayerStatComponent* Stat) { if (HealthBar) { HealthBar->BindToAttributes(ASC,AttributeSet); } - // - // if (ManaBar) - // { - // ManaBar->BindToAttributes(ASC,AttributeSet); - // } if (StaminaBar) { @@ -78,26 +103,12 @@ void UMJHUDWidget::BindAtrributesToChildren(UMJAbilitySystemComponent* ASC, UMJC void UMJHUDWidget::ShowStatPanel() { - if (StatPanel->GetVisibility() == ESlateVisibility::Visible) - { - StatPanel->SetVisibility(ESlateVisibility::Hidden); - } - else if (StatPanel->GetVisibility() == ESlateVisibility::Hidden) - { - StatPanel->SetVisibility(ESlateVisibility::Visible); - } + ToggleWidget(StatPanel); } void UMJHUDWidget::ShowInventory() { - if (Inventory->GetVisibility() == ESlateVisibility::Visible) - { - Inventory->SetVisibility(ESlateVisibility::Hidden); - } - else if (Inventory->GetVisibility() == ESlateVisibility::Hidden) - { - Inventory->SetVisibility(ESlateVisibility::Visible); - } + ToggleWidget(Inventory); } void UMJHUDWidget::ShowStore() @@ -115,14 +126,7 @@ void UMJHUDWidget::ShowStore() void UMJHUDWidget::SetSkillWidgetVisibility() { - if (SkillWidget->GetVisibility() == ESlateVisibility::Visible) - { - SkillWidget->SetVisibility(ESlateVisibility::Hidden); - } - else if (SkillWidget->GetVisibility() == ESlateVisibility::Hidden) - { - SkillWidget->SetVisibility(ESlateVisibility::Visible); - } + ToggleWidget(SkillWidget); } void UMJHUDWidget::SetDialogueVisibility() @@ -130,6 +134,7 @@ void UMJHUDWidget::SetDialogueVisibility() if (Dialogue->GetVisibility() == ESlateVisibility::Visible) { Dialogue->SetVisibility(ESlateVisibility::Hidden); + Dialogue->GetBacklogWidget()->ClearBacklog(); } else if (Dialogue->GetVisibility() == ESlateVisibility::Hidden) { @@ -137,3 +142,42 @@ void UMJHUDWidget::SetDialogueVisibility() } } +void UMJHUDWidget::SetTutorialMouse(TSubclassOf NewWidget) +{ + if (!TutorialMouse) return; + if (!NewWidget) return; + + TutorialMouse->ClearChildren(); // 이전에 있던 마우스 위젯은 제거한다 + + UMJMouseWidget* Mouse = CreateWidget(GetWorld(),NewWidget); + if (Mouse) + { + TutorialMouse->AddChild(Mouse); + } +} + +void UMJHUDWidget::SetMouseVisibility() +{ + ToggleWidget(TutorialMouse); +} + +void UMJHUDWidget::ShowShift() +{ + Shift->SetVisibility(ESlateVisibility::Visible); +} + +void UMJHUDWidget::HideShift() +{ + Shift->SetVisibility(ESlateVisibility::Hidden); +} + +void UMJHUDWidget::SetInstructionWidgetVisibility() +{ + ToggleWidget(Instruction); +} + +void UMJHUDWidget::SetInstructionText(const FString& InInstruction) +{ + Instruction->SetInstructionText(InInstruction); +} + diff --git a/Source/ProjectMJ/UI/MJHUDWidget.h b/Source/ProjectMJ/UI/MJHUDWidget.h index c707e624..31a2e759 100644 --- a/Source/ProjectMJ/UI/MJHUDWidget.h +++ b/Source/ProjectMJ/UI/MJHUDWidget.h @@ -14,6 +14,9 @@ * Last Modified Date: */ +class UBorder; +class UMJTutorialInstruction; +class UMJMouseWidget; class UMJEquipedSkillWidget; class UMJSkillWidget; class UMJUIToggle; @@ -66,10 +69,34 @@ class PROJECTMJ_API UMJHUDWidget : public UUserWidget UPROPERTY(meta = (BindWidget)) TObjectPtr EquipedSkillWidget; + + // Tutorial Widget + UPROPERTY(meta = (BindWidget)) + TObjectPtr TutorialMouse; + + UPROPERTY(EditDefaultsOnly, Category = SettingWidgetClass) + TSubclassOf LeftMouseClass; + + UPROPERTY(EditDefaultsOnly, Category = SettingWidgetClass) + TSubclassOf RightMouseClass; + + UPROPERTY(EditDefaultsOnly, Category = SettingWidgetClass) + TSubclassOf RightPressMouseClass; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr Shift; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr Instruction; + + public: UFUNCTION() virtual void NativeConstruct() override; + UFUNCTION() + void ToggleWidget(UWidget* Widget); + UFUNCTION() void BindAtrributesToChildren(class UMJAbilitySystemComponent* ASC, class UMJCharacterAttributeSet* AttributeSet, class UMJPlayerStatComponent* Stat); @@ -88,6 +115,34 @@ class PROJECTMJ_API UMJHUDWidget : public UUserWidget UFUNCTION() void SetDialogueVisibility(); + UFUNCTION() + void SetTutorialMouse(TSubclassOf NewWidget); + + UFUNCTION() + void SetMouseVisibility(); + + UFUNCTION() + void SetLeftMouse() {SetTutorialMouse(LeftMouseClass);} + + UFUNCTION() + void SetRightMouse() {SetTutorialMouse(RightMouseClass);} + + UFUNCTION() + void SetRightPressMouse() {SetTutorialMouse(RightPressMouseClass);} + + UFUNCTION() + void ShowShift(); + + UFUNCTION() + void HideShift(); + + UFUNCTION() + void SetInstructionWidgetVisibility(); + + UFUNCTION() + void SetInstructionText(const FString& InInstruction); + + // UMJInventoryWidget* GetInventoryWidget() {return Inventory;}; UMJStoreWidget* GetStoreWidget() {return Store;}; UMJDialogueWidget* GetDialogueWidget() {return Dialogue;}; diff --git a/Source/ProjectMJ/UI/MJUIManagerSubsystem.h b/Source/ProjectMJ/UI/MJUIManagerSubsystem.h index 4a7506df..667514f6 100644 --- a/Source/ProjectMJ/UI/MJUIManagerSubsystem.h +++ b/Source/ProjectMJ/UI/MJUIManagerSubsystem.h @@ -49,10 +49,17 @@ class PROJECTMJ_API UMJUIManagerSubsystem : public UGameInstanceSubsystem void ShowStore(); void SetSkillWidgetVisibility(); + + bool GetbHasRun() {return bHasRun;} + void SetbHasRun(bool b) {bHasRun = b;} + protected: UPROPERTY() TObjectPtr HUDWidget; UPROPERTY() TSubclassOf HUDWidgetClass; + + UPROPERTY() + bool bHasRun = false; }; diff --git a/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.cpp b/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.cpp new file mode 100644 index 00000000..e6f88b00 --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.cpp @@ -0,0 +1,19 @@ +// ThenOneDayStudio + + +#include "UI/Tutorial/MJMouseWidget.h" + +void UMJMouseWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + PlayAnim(); +} + +void UMJMouseWidget::PlayAnim() +{ + if (MouseLeft) + { + PlayAnimation(MouseLeft,0.0f, 0); + } +} diff --git a/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.h b/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.h new file mode 100644 index 00000000..f67520ba --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJMouseWidget.h @@ -0,0 +1,25 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "MJMouseWidget.generated.h" + +/** + * + */ +UCLASS() +class PROJECTMJ_API UMJMouseWidget : public UUserWidget +{ + GENERATED_BODY() +protected: + UPROPERTY(meta = (BindWidgetAnim),Transient) + TObjectPtr MouseLeft; + +public: + virtual void NativeConstruct() override; + + UFUNCTION() + void PlayAnim(); +}; diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.cpp b/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.cpp new file mode 100644 index 00000000..ac84e32e --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.cpp @@ -0,0 +1,20 @@ +// ThenOneDayStudio + + +#include "UI/Tutorial/MJTutorialCollision.h" +#include "Components/BoxComponent.h" + +// Sets default values +AMJTutorialCollision::AMJTutorialCollision() +{ + CollisionBox = CreateDefaultSubobject(TEXT("TutorialCollision")); + RootComponent = CollisionBox; + CollisionBox->SetGenerateOverlapEvents(true); + CollisionBox->SetHiddenInGame(true); +} + +void AMJTutorialCollision::Hide() +{ + Destroy(); +} + diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.h b/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.h new file mode 100644 index 00000000..f8953b67 --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialCollision.h @@ -0,0 +1,41 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "MJTutorialCollision.generated.h" + +class UBoxComponent; + +UENUM(BlueprintType) +enum class ECollisionType : uint8 +{ + AttackTutorial, + InstantSkillTutorial, + ChargeSkillTutorial +}; + +UCLASS() +class PROJECTMJ_API AMJTutorialCollision : public AActor +{ + GENERATED_BODY() + +protected: + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Trigger") + TObjectPtr CollisionBox; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString InstructionText; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + ECollisionType CollisionType; + +public: + AMJTutorialCollision(); + + ECollisionType GetCollisionType() { return CollisionType; } + FString GetInstructionText() { return InstructionText; } + + void Hide(); +}; diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.cpp b/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.cpp new file mode 100644 index 00000000..7070c3fb --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.cpp @@ -0,0 +1,29 @@ +// ThenOneDayStudio + + +#include "UI/Tutorial/MJTutorialInstruction.h" + +#include "Components/TextBlock.h" + +void UMJTutorialInstruction::NativeConstruct() +{ + Super::NativeConstruct(); + + PlayAnim(); +} + +void UMJTutorialInstruction::PlayAnim() +{ + if (InstructionAnim) + { + PlayAnimation(InstructionAnim,0.0f, 0); + } +} + +void UMJTutorialInstruction::SetInstructionText(const FString& InInstruction) +{ + if (InstructionText) + { + InstructionText->SetText(FText::FromString(InInstruction)); + } +} diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.h b/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.h new file mode 100644 index 00000000..1400db3a --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialInstruction.h @@ -0,0 +1,33 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "MJTutorialInstruction.generated.h" + +class UTextBlock; +/** + * + */ +UCLASS() +class PROJECTMJ_API UMJTutorialInstruction : public UUserWidget +{ + GENERATED_BODY() + +protected: + UPROPERTY(meta = (BindWidgetAnim),Transient) + TObjectPtr InstructionAnim; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr InstructionText; + +public: + virtual void NativeConstruct() override; + + UFUNCTION() + void PlayAnim(); + + UFUNCTION() + void SetInstructionText(const FString& InInstruction); +}; diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.cpp b/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.cpp new file mode 100644 index 00000000..ab883b3a --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.cpp @@ -0,0 +1,14 @@ +// ThenOneDayStudio + + +#include "UI/Tutorial/MJTutorialStartDialogueComponent.h" + +void UMJTutorialStartDialogueComponent::ProceedStory() +{ + TurnOver(); + if (IsDialogueEnd()) + { + OnTutorialStartDialogueEnd.Broadcast(); + } + +} diff --git a/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.h b/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.h new file mode 100644 index 00000000..e0b2e8f9 --- /dev/null +++ b/Source/ProjectMJ/UI/Tutorial/MJTutorialStartDialogueComponent.h @@ -0,0 +1,23 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "Dialogue/MJDialogueComponent.h" +#include "MJTutorialStartDialogueComponent.generated.h" + +/** + * + */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTutorialStartDialogueEnd); +UCLASS() +class PROJECTMJ_API UMJTutorialStartDialogueComponent : public UMJDialogueComponent +{ + GENERATED_BODY() + +public: + FOnTutorialStartDialogueEnd OnTutorialStartDialogueEnd; + + UFUNCTION() + void ProceedStory(); +}; diff --git a/Source/ProjectMJ/UI/World/MJDetectionWidget.cpp b/Source/ProjectMJ/UI/World/MJDetectionWidget.cpp new file mode 100644 index 00000000..cdc71c67 --- /dev/null +++ b/Source/ProjectMJ/UI/World/MJDetectionWidget.cpp @@ -0,0 +1,20 @@ +// ThenOneDayStudio + + +#include "UI/World/MJDetectionWidget.h" + +void UMJDetectionWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + PlayAnim(); +} + +void UMJDetectionWidget::PlayAnim() +{ + if (Detection) + { + PlayAnimation(Detection); + } + +} diff --git a/Source/ProjectMJ/UI/World/MJDetectionWidget.h b/Source/ProjectMJ/UI/World/MJDetectionWidget.h new file mode 100644 index 00000000..61b7531d --- /dev/null +++ b/Source/ProjectMJ/UI/World/MJDetectionWidget.h @@ -0,0 +1,23 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "MJDetectionWidget.generated.h" + +/** + * + */ +UCLASS() +class PROJECTMJ_API UMJDetectionWidget : public UUserWidget +{ + GENERATED_BODY() + +protected: + UPROPERTY(meta = (BindWidgetAnim), Transient) + TObjectPtr Detection; +public: + virtual void NativeConstruct() override; + void PlayAnim(); +};