// Fill out your copyright notice in the Description page of Project Settings. #include "DialogueNPC.h" #include "Blueprint/UserWidget.h" #include "Components/TextBlock.h" #include "GameFramework/Character.h" // Sets default values for this component's properties UDialogueNPC::UDialogueNPC() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = true; static ConstructorHelpers::FClassFinder DialogueWidgetClass(TEXT("/Game/Dialogue/TextPrompt")); DialogueWidget = DialogueWidgetClass.Class; } // Called when the game starts void UDialogueNPC::BeginPlay() { Super::BeginPlay(); DialogueWidgetInstance = CreateWidget(GetWorld(), DialogueWidget); NPCNameText = Cast(DialogueWidgetInstance->GetWidgetFromName("Text_Name")); DialogueText = Cast(DialogueWidgetInstance->GetWidgetFromName("Text_Dialogue")); NextButton = Cast(DialogueWidgetInstance->GetWidgetFromName("Button_Next")); NextButton->OnClicked.AddDynamic(this, &UDialogueNPC::NextDialogue); NPCPortraitImage = Cast(DialogueWidgetInstance->GetWidgetFromName("Image_Portrait")); if (IsValid(NPCPortrait)) NPCPortraitImage->SetBrushFromTexture(NPCPortrait); Choice1Button = Cast(DialogueWidgetInstance->GetWidgetFromName("Button_Choice1")); Choice1Button->OnClicked.AddDynamic(this, &UDialogueNPC::Choice1); Choice2Button = Cast(DialogueWidgetInstance->GetWidgetFromName("Button_Choice2")); Choice2Button->OnClicked.AddDynamic(this, &UDialogueNPC::Choice2); Choice3Button = Cast(DialogueWidgetInstance->GetWidgetFromName("Button_Choice3")); Choice3Button->OnClicked.AddDynamic(this, &UDialogueNPC::Choice3); Choice1Text = Cast(DialogueWidgetInstance->GetWidgetFromName("Text_Choice1")); Choice2Text = Cast(DialogueWidgetInstance->GetWidgetFromName("Text_Choice2")); Choice3Text = Cast(DialogueWidgetInstance->GetWidgetFromName("Text_Choice3")); } void UDialogueNPC::NextDialogue() { //Dialogue Skip if (CurrentDialogue.Len() < CurrentDialogueStringPath[DialogueIndex].Len()) { CurrentDialogue = CurrentDialogueStringPath[DialogueIndex]; DialogueText->SetText(FText::FromString(CurrentDialogue)); return; } DialogueIndex++; if (DialogueIndex >= CurrentDialogueStringPath.Num()) { if (CurrentDialoguePath->Choices.IsEmpty()) { EndDialogue(); return; } GetWorld()->GetTimerManager().PauseTimer(TextAnimationTimerHandle); DialogueText->SetText(FText::FromString("")); Choice1Button->SetVisibility(ESlateVisibility::Visible); Choice2Button->SetVisibility(ESlateVisibility::Visible); if (Choice3Text->GetText().ToString() != "") Choice3Button->SetVisibility(ESlateVisibility::Visible); NextButton->SetVisibility(ESlateVisibility::Hidden); return; } CurrentDialogue = ""; } void UDialogueNPC::NextCharacter() { if (DialogueIndex >= CurrentDialogueStringPath.Num()) return; if (CurrentDialogue.Len() < CurrentDialogueStringPath[DialogueIndex].Len()) { CurrentDialogue.AppendChar(CurrentDialogueStringPath[DialogueIndex][CurrentDialogue.Len()]); DialogueText->SetText(FText::FromString(CurrentDialogue)); } } // Called every frame void UDialogueNPC::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // ... } void UDialogueNPC::StartDialogue() { if (IsValid(RootDialoguePath)) CurrentDialogueStringPath = RootDialoguePath->Dialogue; if (CurrentDialogueStringPath.IsEmpty()) { UE_LOG(LogTemp, Warning, TEXT("Dialogue Path is Empty")); return; } //Disable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->DisableInput(GetWorld()->GetFirstPlayerController()); } //Set to UI Mode Only APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeUIOnly()); PlayerController->bShowMouseCursor = true; Choice1Button->SetVisibility(ESlateVisibility::Hidden); Choice2Button->SetVisibility(ESlateVisibility::Hidden); Choice3Button->SetVisibility(ESlateVisibility::Hidden); DialogueText->SetText(FText::FromString("")); DialogueWidgetInstance->AddToViewport(); NPCNameText->SetText(FText::FromString(NPCName)); DialogueIndex = 0; CurrentDialogue = ""; CurrentDialoguePath = RootDialoguePath; CurrentDialogueStringPath = RootDialoguePath->Dialogue; GetWorld()->GetTimerManager().SetTimer(TextAnimationTimerHandle, this, &UDialogueNPC::NextCharacter, TextAnimationSpeed, true); } void UDialogueNPC::EndDialogue() { TextAnimationTimerHandle.Invalidate(); DialogueWidgetInstance->RemoveFromParent(); //Enable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->EnableInput(GetWorld()->GetFirstPlayerController()); } //Reset UI Mode APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeGameOnly()); PlayerController->bShowMouseCursor = false; } UDialoguePath* UDialogueNPC::CreateRootDialoguePath() { RootDialoguePath = NewObject(); return RootDialoguePath; } UDialoguePath* UDialogueNPC::AddDialogue(UDialoguePath* DialoguePath, FText TextInput) { if (TextInput.IsEmpty()) return DialoguePath; DialoguePath->Dialogue.Add(TextInput.ToString()); return DialoguePath; } void UDialogueNPC::AddChoices(UDialoguePath* ParentPath, FText ChoiceText1, FText ChoiceText2, FText ChoiceText3, UDialoguePath*& Out_ChoicePath1, UDialoguePath*& Out_ChoicePath2, UDialoguePath*& Out_ChoicePath3) { ParentPath->Choices.Add(NewObject()); ParentPath->Choices.Add(NewObject()); ParentPath->Choices.Add(NewObject()); Out_ChoicePath1 = ParentPath->Choices[0]; Out_ChoicePath2 = ParentPath->Choices[1]; Out_ChoicePath3 = ParentPath->Choices[2]; Choice1Text->SetText(ChoiceText1); Choice2Text->SetText(ChoiceText2); Choice3Text->SetText(ChoiceText3); } void UDialogueNPC::Choice1() { CurrentDialoguePath = CurrentDialoguePath->Choices[0]; DialogueIndex = 0; CurrentDialogue = ""; CurrentDialogueStringPath = CurrentDialoguePath->Dialogue; GetWorld()->GetTimerManager().UnPauseTimer(TextAnimationTimerHandle); Choice1Button->SetVisibility(ESlateVisibility::Hidden); Choice2Button->SetVisibility(ESlateVisibility::Hidden); Choice3Button->SetVisibility(ESlateVisibility::Hidden); NextButton->SetVisibility(ESlateVisibility::Visible); } void UDialogueNPC::Choice2() { CurrentDialoguePath = CurrentDialoguePath->Choices[1]; DialogueIndex = 0; CurrentDialogue = ""; CurrentDialogueStringPath = CurrentDialoguePath->Dialogue; GetWorld()->GetTimerManager().UnPauseTimer(TextAnimationTimerHandle); Choice1Button->SetVisibility(ESlateVisibility::Hidden); Choice2Button->SetVisibility(ESlateVisibility::Hidden); Choice3Button->SetVisibility(ESlateVisibility::Hidden); NextButton->SetVisibility(ESlateVisibility::Visible); } void UDialogueNPC::Choice3() { CurrentDialoguePath = CurrentDialoguePath->Choices[2]; DialogueIndex = 0; CurrentDialogue = ""; CurrentDialogueStringPath = CurrentDialoguePath->Dialogue; GetWorld()->GetTimerManager().UnPauseTimer(TextAnimationTimerHandle); Choice1Button->SetVisibility(ESlateVisibility::Hidden); Choice2Button->SetVisibility(ESlateVisibility::Hidden); Choice3Button->SetVisibility(ESlateVisibility::Hidden); NextButton->SetVisibility(ESlateVisibility::Visible); }