ASC学习笔记0009:用于注册确认/取消输入的回调

中文注释:UrealEngine-5.2.1源码-AbilitySystemComponent.h

学习内容:

/** 用于注册确认/取消输入的回调 */
	DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAbilityConfirmOrCancel);

一. 这是一个 Unreal Engine 中使用的宏,用于声明动态多播委托。让我为您详细解释这个声明:

语法解析

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAbilityConfirmOrCancel)
  • DECLARE_DYNAMIC_MULTICAST_DELEGATE - UE4/UE5 的宏,用于声明动态多播委托

  • FAbilityConfirmOrCancel - 委托的名称,遵循 UE 的命名约定(F 前缀)

等效展开

这个宏大致会展开为:

class FAbilityConfirmOrCancel : public FMulticastDelegateBase
{
    // 动态委托支持序列化、反射等功能
    // 可以绑定多个函数,并一次性广播调用
};

使用场景

这种委托通常用于:

1. 技能系统的确认/取消

// 在技能组件中
UCLASS()
class UAbilitySystemComponent : public UActorComponent
{
    GENERATED_BODY()
    
public:
    FAbilityConfirmOrCancel OnAbilityConfirmed;
    FAbilityConfirmOrCancel OnAbilityCancelled;
    
    void ConfirmAbility()
    {
        OnAbilityConfirmed.Broadcast();
    }
    
    void CancelAbility()
    {
        OnAbilityCancelled.Broadcast();
    }
};

2. 绑定回调函数

// 在玩家控制器或UI中
void AMyPlayerController::SetupAbilityDelegates()
{
    UAbilitySystemComponent* AbilityComp = GetAbilitySystemComponent();
    
    // 绑定确认回调
    AbilityComp->OnAbilityConfirmed.AddDynamic(this, &AMyPlayerController::HandleAbilityConfirmed);
    
    // 绑定取消回调
    AbilityComp->OnAbilityCancelled.AddDynamic(this, &AMyPlayerController::HandleAbilityCancelled);
}

void AMyPlayerController::HandleAbilityConfirmed()
{
    // 处理技能确认逻辑
    UE_LOG(LogTemp, Warning, TEXT("Ability confirmed!"));
}

void AMyPlayerController::HandleAbilityCancelled()
{
    // 处理技能取消逻辑
    UE_LOG(LogTemp, Warning, TEXT("Ability cancelled!"));
}

特点

  1. 多播 - 可以绑定多个回调函数

  2. 动态 - 支持序列化、蓝图暴露、反射

  3. 无参数 - 这个特定委托没有参数

  4. 广播调用 - 使用 .Broadcast() 触发所有绑定的函数

带参数的版本

如果需要参数,可以使用带参数的委托宏:

// 带一个参数的版本
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityConfirmOrCancel, bool, bWasConfirmed);

// 使用时
OnAbilityConfirmed.Broadcast(true);

这种委托在 UE 的游戏技能系统、UI 交互、事件系统中非常常见。

二. 在实战项目中,FAbilityConfirmOrCancel 这类委托在技能系统、交互系统和UI系统中有着广泛的应用。以下是一些具体的实际用例:

1. 技能瞄准确认系统

技能基类中声明:

// GameplayAbilityBase.h
UCLASS()
class AGameplayAbilityBase : public UGameplayAbility
{
    GENERATED_BODY()

public:
    /** 确认释放技能 */
    UPROPERTY(BlueprintAssignable, Category = "Ability")
    FAbilityConfirmOrCancel OnAbilityConfirm;
    
    /** 取消技能释放 */
    UPROPERTY(BlueprintAssignable, Category = "Ability")  
    FAbilityConfirmOrCancel OnAbilityCancel;

    // 触发确认(通常在玩家点击鼠标右键或确认键时调用)
    UFUNCTION(BlueprintCallable)
    void TriggerConfirm() { OnAbilityConfirm.Broadcast(); }
    
    // 触发取消(通常在玩家按下取消键时调用)
    UFUNCTION(BlueprintCallable)
    void TriggerCancel() { OnAbilityCancel.Broadcast(); }
};
 

具体技能实现:

// Ability_Fireball.cpp
void AAbility_Fireball::OnActivate()
{
    // 进入瞄准模式
    EnterAimingMode();
    
    // 绑定确认/取消事件
    OnAbilityConfirm.AddDynamic(this, &AAbility_Fireball::SpawnFireball);
    OnAbilityCancel.AddDynamic(this, &AAbility_Fireball::CleanupAiming);
}

void AAbility_Fireball::SpawnFireball()
{
    // 生成火球逻辑
    AFireballProjectile* Fireball = GetWorld()->SpawnActor<AFireballProjectile>();
    // ... 火球初始化
}

void AAbility_Fireball::CleanupAiming()
{
    // 清理瞄准效果
    DestroyAimingIndicator();
    // 退还技能资源
    RefundAbilityCost();
}
 

2. 交互确认系统

对话选择确认:

// DialogueSystem.cpp
void UDialogueWidget::ShowChoice(const FText& Question, const TArray<FText>& Choices)
{
    // 显示选择UI
    DisplayChoiceWidget(Question, Choices);
    
    // 绑定确认委托
    GetOnConfirm().AddDynamic(this, &UDialogueWidget::OnChoiceConfirmed);
    GetOnCancel().AddDynamic(this, &UDialogueWidget::OnChoiceCancelled);
}

void UDialogueWidget::OnChoiceConfirmed()
{
    // 确认选择
    int32 SelectedIndex = GetCurrentSelectedIndex();
    ExecuteChoice(SelectedIndex);
    HideChoiceWidget();
}

void UDialogueWidget::OnChoiceCancelled()
{
    // 取消选择,可能回到上级菜单或关闭对话
    if(CanGoBack()) {
        GoBackToPreviousMenu();
    } else {
        CloseDialogue();
    }
}
 

3. 建造系统确认

建筑放置确认:

// BuildingSystem.cpp
void ABuildingGhost::BeginPlay()
{
    Super::BeginPlay();
    
    // 绑定输入委托
    PlayerController->OnConfirmAction.AddDynamic(this, &ABuildingGhost::ConfirmPlacement);
    PlayerController->OnCancelAction.AddDynamic(this, &ABuildingGhost::CancelPlacement);
}

void ABuildingGhost::ConfirmPlacement()
{
    if(IsValidPlacement())
    {
        // 生成实际建筑
        SpawnActualBuilding();
        // 播放建造音效
        PlayConstructionSound();
        // 消耗资源
        DeductBuildingCost();
        Destroy();
    }
    else
    {
        // 播放无效位置反馈
        PlayInvalidPlacementEffect();
    }
}

void ABuildingGhost::CancelPlacement()
{
    // 取消建造,退还预览资源
    RefundPreviewCost();
    // 播放取消效果
    PlayCancelEffect();
    Destroy();
}
 

4. UI 弹窗确认系统

设置保存确认:

// SettingsWidget.cpp
void USettingsWidget::ShowUnsavedChangesDialog()
{
    // 显示"有未保存的更改"弹窗
    ShowConfirmationDialog(
        FText::FromString("有未保存的更改"),
        FText::FromString("是否保存更改?"),
        FAbilityConfirmOrCancel::CreateUObject(this, &USettingsWidget::OnSaveConfirm),
        FAbilityConfirmOrCancel::CreateUObject(this, &USettingsWidget::OnSaveCancel)
    );
}

void USettingsWidget::OnSaveConfirm()
{
    SaveSettings();
    CloseSettings();
}

void USettingsWidget::OnSaveCancel()
{
    // 不保存直接关闭
    ReloadOriginalSettings();
    CloseSettings();
}
 

5. 网络游戏中的同步应用

多人技能同步:

// MultiplayerAbility.cpp
void UMultiplayerAbility::Server_RequestConfirm_Implementation(APlayerController* Player)
{
    // 服务器验证后广播给所有客户端
    if(ValidateConfirmation(Player))
    {
        // 服务器执行
        ExecuteConfirmLogic();
        
        // 广播给所有客户端
        Multicast_OnConfirmed();
    }
}

void UMultiplayerAbility::Multicast_OnConfirmed_Implementation()
{
    // 所有客户端执行确认效果
    OnAbilityConfirm.Broadcast();
    
    // 播放确认视觉效果
    PlayConfirmEffects();
}
 

6. 实际项目中的最佳实践

委托管理:

// 安全的委托绑定
void UMyAbility::BindDelegates()
{
    // 先清除之前的绑定
    OnAbilityConfirm.Clear();
    OnAbilityCancel.Clear();
    
    // 重新绑定
    OnAbilityConfirm.AddDynamic(this, &UMyAbility::HandleConfirm);
    OnAbilityCancel.AddDynamic(this, &UMyAbility::HandleCancel);
}

// 确保在适当的时候清理
void UMyAbility::EndAbility()
{
    OnAbilityConfirm.Clear();
    OnAbilityCancel.Clear();
    Super::EndAbility();
}
 

蓝图集成:

// 暴露给蓝图使用的包装函数
UFUNCTION(BlueprintCallable, Category = "Ability")
void BindToConfirm(FScriptDelegate Delegate)
{
    OnAbilityConfirm.Add(Delegate);
}

UFUNCTION(BlueprintCallable, Category = "Ability")
void BindToCancel(FScriptDelegate Delegate)
{
    OnAbilityCancel.Add(Delegate);
}
 

这些实际应用展示了 FAbilityConfirmOrCancel 在游戏开发中的强大灵活性,特别是在需要用户决策的交互场景中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值