😸

【UE5】自作AbilityTaskにDelegateを使って分岐処理を追加する

2024/10/24に公開

概要

AbilityTaskなど、一部のノードには分岐処理が含まれてるものがあります。


PlayMontageAndWaitの例

これの追加の仕方がわからなかったので、調べたことをまとめて記事にしました。

環境

UE5.4.4

やり方

参考にまずはAbilityTask_PlayMontageAndWait.hの中身を見てみます。
中身を見てみると、DECLARE_DYNAMIC_MULTICAST_DELEGATEのDelegate(※DECLARE_MULTICAST_DELEGATEだとコンパイルエラーになりました)が用意されていて、先程分岐先と同じ名前の変数をUPROPERTY(BlueprintAssignable)で用意してありました。
それら用意した変数をBroadcast処理を呼ぶと、各種分岐処理が呼ばれるようになっていました。

Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public\Abilities\Tasks\AbilityTask_PlayMontageAndWait.h
//インクルードなどは省略

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMontageWaitSimpleDelegate);

UCLASS()
class GAMEPLAYABILITIES_API UAbilityTask_PlayMontageAndWait : public UAbilityTask
{
    //省略

    UPROPERTY(BlueprintAssignable)
    FMontageWaitSimpleDelegate	OnCompleted;

    UPROPERTY(BlueprintAssignable)
    FMontageWaitSimpleDelegate	OnBlendOut;

    UPROPERTY(BlueprintAssignable)
    FMontageWaitSimpleDelegate	OnInterrupted;

    UPROPERTY(BlueprintAssignable)
    FMontageWaitSimpleDelegate	OnCancelled;
	
    //省略
}

なので、こういった感じのクラスを用意してテストしてみました。

UAbilityTask_ExampleAddBranchEvent.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "AbilityTask_ExampleAddBranchEvent.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FExampleAddBranchEvent);

UCLASS()
class COMMONDIALOG_API UAbilityTask_ExampleAddBranchEvent : public UAbilityTask
{
    GENERATED_BODY()
public:
    UPROPERTY(BlueprintAssignable)
    FExampleAddBranchEvent OnOne;
    
    UPROPERTY(BlueprintAssignable)
    FExampleAddBranchEvent OnTwo;
    
    virtual void Activate() override;
    
    UFUNCTION(BlueprintCallable,meta=(HidePin = "OwnerAbility", DefaultToSelf = "OwnerAbility"))
    static UAbilityTask_ExampleAddBranchEvent* WaitExampleAddBranchEvent(UGameplayAbility* OwnerAbility);
private:
    void OnAfterOneSeconds();
    void OnAfterTwoSeconds();
};


UAbilityTask_ExampleAddBranchEvent.cpp
// Fill out your copyright notice in the Description page of Project Settings.


#include "AbilityTask_ExampleAddBranchEvent.h"

void UAbilityTask_ExampleAddBranchEvent::Activate()
{
    Super::Activate();
    UWorld* World = GetWorld();

    //1秒後に処理を呼ぶ
    FTimerHandle OneTimerHandle;
    World->GetTimerManager().SetTimer(OneTimerHandle, this, &UAbilityTask_ExampleAddBranchEvent::OnAfterOneSeconds, (float)1, false);
    
    //2秒後に処理を呼ぶ
    FTimerHandle TwoTimeHandle;
    World->GetTimerManager().SetTimer(TwoTimeHandle, this, &UAbilityTask_ExampleAddBranchEvent::OnAfterTwoSeconds, (float)2, false);
}

UAbilityTask_ExampleAddBranchEvent* UAbilityTask_ExampleAddBranchEvent::WaitExampleAddBranchEvent(
    UGameplayAbility* OwnerAbility)
{
    UAbilityTask_ExampleAddBranchEvent* MyTask = NewAbilityTask<UAbilityTask_ExampleAddBranchEvent>(OwnerAbility);
    return MyTask;
}

void UAbilityTask_ExampleAddBranchEvent::OnAfterOneSeconds()
{
    OnOne.Broadcast();
}

void UAbilityTask_ExampleAddBranchEvent::OnAfterTwoSeconds()
{
    OnTwo.Broadcast();
    
    //終わるトリガーがないのでここで終わらす
    EndTask();
}

今回はタイマーを使って1秒後と2秒後にイベントを発火させて各種Broadcastを呼び、分岐処理をさせるようにしました。

BPはこんな感じにしました。

実際に呼ばれてる様子
https://x.com/daria_nicht/status/1849105418288832948

Discussion