当前位置: 首页 > news >正文

ASC学习笔记0008:用于注册能力按键输入的回调

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

学习内容:

/** 用于注册能力按键输入的回调 */DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityAbilityKey, /*UGameplayAbility*, Ability, */int32, InputID);

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

语法分析

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityAbilityKey,     // 委托类型名称/*UGameplayAbility*, Ability, */  // 被注释掉的参数int32, InputID          // 实际的参数类型和名称
);

实际效果

这个宏会生成一个名为 FAbilityAbilityKey 的动态多播委托,其签名相当于:

// 生成的委托签名(概念上)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityAbilityKey, int32, InputID);// 对应的函数签名
void Broadcast(int32 InputID);

在 Gameplay Ability System 中的用途

这个委托通常用于处理能力系统的输入绑定:

// 在 Ability System Component 中
UPROPERTY(BlueprintAssignable, Category = "Abilities")
FAbilityAbilityKey AbilityKeyPressed;// 绑定回调
AbilitySystemComponent->AbilityKeyPressed.AddDynamic(this, &AMyCharacter::OnAbilityKeyPressed);// 回调函数实现
UFUNCTION()
void OnAbilityKeyPressed(int32 InputID) {// 处理对应 InputID 的能力激活UE_LOG(LogTemp, Warning, TEXT("Ability key pressed: %d"), InputID);
}

注意事项

  1. 注释掉的参数:原本可能设计为传递 UGameplayAbility* 和能力,但最终只保留了 InputID

  2. 命名重复:委托名称 FAbilityAbilityKey 中的 "Ability" 重复了,可能是笔误

  3. 建议的改进命名

    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAbilityInput, int32, InputID);

这个委托让您可以在蓝图中或 C++ 中绑定回调,当玩家按下绑定的能力按键时触发相应的游戏能力。

二. 在真实的游戏项目中,这种能力按键委托在能力系统中有着广泛而核心的应用。以下是一些具体的实际应用场景:

1. 玩家输入与能力绑定

输入组件中的绑定

// 在玩家控制器或角色中
void AMyPlayerController::SetupInputComponent()
{Super::SetupInputComponent();InputComponent->BindAction("Ability1", IE_Pressed, this, &AMyPlayerController::OnAbility1Pressed);InputComponent->BindAction("Ability2", IE_Pressed, this, &AMyPlayerController::OnAbility2Pressed);
}void AMyPlayerController::OnAbility1Pressed()
{// 触发能力按键委托,InputID 对应能力槽位AbilitySystemComponent->OnAbilityKeyPressed.Broadcast(1);
}void AMyPlayerController::OnAbility2Pressed()
{AbilitySystemComponent->OnAbilityKeyPressed.Broadcast(2);
}
 

2. 能力系统组件中的处理

// 在自定义 AbilitySystemComponent 中
UMyAbilitySystemComponent::UMyAbilitySystemComponent()
{// 绑定委托OnAbilityKeyPressed.AddDynamic(this, &UMyAbilitySystemComponent::HandleAbilityInput);
}void UMyAbilitySystemComponent::HandleAbilityInput(int32 InputID)
{if (!OwnerActor || OwnerActor->IsPendingKill())return;// 查找对应输入ID的能力FGameplayAbilitySpec* AbilitySpec = FindAbilitySpecFromInputID(InputID);if (AbilitySpec && AbilitySpec->Ability){// 尝试激活能力TryActivateAbility(AbilitySpec->Handle);}
}
 

3. UI 技能栏集成

技能栏按钮点击

// 技能栏UI组件
void USkillBarWidget::OnSkillButtonClicked(int32 SlotIndex)
{if (APlayerController* PC = GetOwningPlayer()){if (UMyAbilitySystemComponent* ASC = GetAbilitySystemComponent()){// 通过委托通知能力系统ASC->OnAbilityKeyPressed.Broadcast(SlotIndex);}}
}
 

4. 复杂的输入上下文系统

// 支持不同上下文下的输入重映射
void UInputContextManager::HandleGlobalAbilityInput(int32 InputID)
{// 根据当前上下文获取映射后的能力IDint32 MappedAbilityID = GetMappedAbilityID(CurrentContext, InputID);// 广播映射后的IDAbilitySystem->OnAbilityKeyPressed.Broadcast(MappedAbilityID);
}
 

5. 连招系统集成

// 连招管理器
UComboManager::UComboManager()
{// 监听能力按键OnAbilityKeyPressed.AddDynamic(this, &UComboManager::OnAbilityInputReceived);
}void UComboManager::OnAbilityInputReceived(int32 InputID)
{// 记录输入时间戳FInputRecord NewRecord;NewRecord.InputID = InputID;NewRecord.Timestamp = GetWorld()->GetTimeSeconds();InputHistory.Add(NewRecord);// 检测连招CheckForCombo();
}
 

6. 平台特定适配

// 处理不同平台的输入差异
void UCrossPlatformInputHandler::HandleTouchInput(int32 TouchIndex, FVector2D Location)
{// 将触摸位置转换为能力IDint32 AbilityID = ConvertTouchToAbilityID(Location);if (AbilityID != INDEX_NONE){OnAbilityKeyPressed.Broadcast(AbilityID);}
}void UCrossPlatformInputHandler::HandleControllerInput(FKey Key)
{// 手柄按键映射到能力IDint32 AbilityID = ControllerMapping.FindRef(Key);if (AbilityID != INDEX_NONE){OnAbilityKeyPressed.Broadcast(AbilityID);}
}
 

7. AI 指令系统

// AI控制器下达能力使用指令
void AAIAbilityController::IssueAbilityCommand(int32 AbilityID, AActor* Target)
{// AI也可以通过相同的接口触发能力if (UAbilitySystemComponent* ASC = Pawn->FindComponentByClass<UAbilitySystemComponent>()){ASC->OnAbilityKeyPressed.Broadcast(AbilityID);// 记录AI决策LogAIAbilityUsage(AbilityID, Target);}
}
 

8. 回放和调试系统

// 能力输入记录和回放
void UAbilityReplaySystem::RecordAbilityInput(int32 InputID)
{FReplayFrame Frame;Frame.InputID = InputID;Frame.Timestamp = GetWorld()->GetTimeSeconds();ReplayData.Add(Frame);// 同时广播给实时系统OnAbilityKeyPressed.Broadcast(InputID);
}void UAbilityReplaySystem::ReplayInputs()
{for (const FReplayFrame& Frame : ReplayData){// 在回放时模拟输入GetWorld()->GetTimerManager().SetTimerForNextTick([this, Frame]() {OnAbilityKeyPressed.Broadcast(Frame.InputID);});}
}
 

实际项目中的优势

  1. 解耦设计 - 输入系统不需要了解具体能力实现

  2. 统一接口 - 键盘、鼠标、手柄、触摸屏都使用相同的委托

  3. 扩展性 - 轻松添加新的输入源或能力类型

  4. 调试友好 - 可以集中监控所有能力输入事件

  5. 网络同步 - 在多人游戏中容易同步输入事件

这种模式在《堡垒之夜》、《英雄联盟》等大型游戏中得到了广泛应用,是构建复杂能力系统的核心架构之一。

http://www.dtcms.com/a/611085.html

相关文章:

  • 邯郸市做网站广西远昌建设公司
  • 网站标题切换无版权的图片素材网站
  • Linux入门---vim编辑器
  • 网站建设服务代理商全面的上海代理注册公司
  • 8.Collections.synchronizedMap 与 ConcurrentMap 的区别与适用场景
  • PHP操作redis
  • Spring Boot 多数据源解决方案:dynamic-datasource-spring-boot-starter 的奥秘(上)
  • 戴尔的网站建设福州网站建设营销方案
  • Redis 面试题精编(70道|含答案|分类整理)
  • 苏州做公司网站设计的公司网站建设项目执行进度表
  • 发布网站域名设置wordpress 搭建 查分系统
  • 四旋翼无人机视觉目标跟踪系统完整实现指南
  • 网站建设与管理案例柳洪轶苏州保洁公司招聘保洁区域经理
  • 中国核工业华兴建设有限公司网站c蔡甸区城乡建设局网站
  • 如何使用C语言反编译程序 | 反编译技术和注意事项
  • 免费设计签名在线生成网络推广seo怎么弄
  • 威海住房和城乡建设厅网站新国标小区网络建设
  • 河北建设厅官方网站聊城网站建设工作室
  • AURIX与tasking改变字体大小
  • MySQL 条件唯一索引实战:用 delete_time 实现活跃记录唯一
  • ⭐ TIE Cell(Tie-High / Tie-Low)完整技术总结与工程指导
  • 淘宝网站c 设计怎么做wordpress屏蔽右键
  • 苏州网站制作公司合肥建设网
  • 简化接口测试:利用Dify工作流结合CI/CD,实现一键式回归验证
  • 网站建设宣传方案三更app下载网站
  • 济宁祥云网站建设深圳龙华是低风险区吗
  • 如何利用个人nas做网站广州市建设局官方网站
  • Linux内核LED驱动开发:实现可控制闪烁与常亮的GPIO驱动
  • 信息论(四):熵与概率分布的期望
  • 辽宁网站网站建设刚刚中国突然宣布