Hi all, I’m currently working with the CommonConversation plugin, where I’ve created a Task which is designed to take a UDialogueWave and play the dialogue audio, and wait until the dialogue audio has completed playing before moving to the next node in the Conversation graph…
So for those unfamiliar with the CommonConversation Tasks yet, when the Task node is reached, it calls ExecuteTaskNode on the custom task, for which must return an FConversationTaskResult once it completes execution telling the graph whether it can continue advancement, abort advancement, etc.
What I need to do is block returning any result until the audio has completed playing, and then return an AdvanceConversation result… My current thought, is to create an FTimerDelegate to execute a function when the audio completes, but of course timed delegates are non-blocking… So I then looked into TFuture’s, could I call the timed delegate, set the value of the future inside the delegate function, and meanwhile in my ExecuteTaskNode call a TFuture::Wait() to block execution until the value of the future is set by the delegate, like so…
// Snippet from ExecuteTaskNode
FTimerDelegate Delegate;
Delegate.BindUFunction(this, FName("OnDialogueCompleted"));
if (AudioComponent->Sound->GetDuration() > 0.f)
{
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, Delegate, AudioComponent->Sound->GetDuration(), false);
FinalizeDialogue.Wait();
}
if (FinalizeDialogue.IsReady())
{
return FinalizeDialogue.Get();
}
void UPlayDialogueTask::OnDialogueCompleted()
{
FinalizeDialogue = FConversationTaskResult::AdvanceConversation();
}
But as it would turn out, you can’t just set TFuture’s values manually, seems like it has to be set by Async()… I wonder if then I could just use TFuture::WaitFor() and just use the duration provided by the AudioComponent to block execution for that long, and then continue execution… e.g.
if (AudioComponent->Sound->GetDuration() > 0.f)
{
// This should always return false
if (FinalizeDialogue.WaitFor(AudioComponent->Sound->GetDuration()))
{
return FinalizeDialogue.Get();
}
return FConversationTaskResult::AdvanceConversation();
}
Any thoughts / suggestions out there?