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

ASC学习笔记0010:效果被应用时的委托

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

学习内容:

/** 效果被应用时的委托 */DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnGameplayEffectAppliedDelegate, UAbilitySystemComponent*, const FGameplayEffectSpec&, FActiveGameplayEffectHandle);

一. 这是一个 Unreal Engine 中 Gameplay Ability System (GAS) 的委托声明。让我为您详细解释这个 FOnGameplayEffectAppliedDelegate

委托结构分析

DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnGameplayEffectAppliedDelegate,       // 委托类型名称UAbilitySystemComponent*,               // 第一个参数类型const FGameplayEffectSpec&,             // 第二个参数类型  FActiveGameplayEffectHandle             // 第三个参数类型
);

参数说明

  1. UAbilitySystemComponent*

    • 指向应用该 Gameplay Effect 的 Ability System Component

    • 通常是目标角色的 ASC

  2. const FGameplayEffectSpec&

    • Gameplay Effect 的规格说明,包含所有配置数据

    • 包括等级、持续时间、修饰符等

  3. FActiveGameplayEffectHandle

    • 激活的 Gameplay Effect 的句柄

    • 用于后续引用和操作该效果

使用示例

绑定委托

// 在某个类中绑定到委托
AbilitySystemComponent->OnGameplayEffectAppliedDelegate.AddUObject(this, &AMyClass::OnGameplayEffectApplied
);

处理函数实现

void AMyClass::OnGameplayEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{// 获取来源和目标信息AActor* SourceActor = Spec.GetEffectContext().GetInstigator();AActor* TargetActor = ASC->GetOwner();// 检查特定的 Gameplay Effectif (Spec.Def->GetFName() == FName("MyEffect")){// 处理特定的效果应用逻辑UE_LOG(LogTemp, Warning, TEXT("MyEffect was applied!"));}// 可以访问效果的其他属性float EffectLevel = Spec.GetLevel();float Duration = Spec.GetDuration();
}

实际应用场景

  • 状态效果触发:当角色获得燃烧、中毒等状态时执行逻辑

  • UI 更新:更新 HUD 显示新获得的效果

  • 音效/特效:播放相应的视觉和听觉反馈

  • 成就系统:追踪特定效果的获得次数

  • 调试工具:监控效果应用情况

这个委托是 GAS 中非常重要的回调机制,让您能够响应游戏中各种状态变化。

二. 在实际项目中,FOnGameplayEffectAppliedDelegate 有广泛的应用场景。以下是一些具体的实际用例:

1. UI 系统 - 状态效果显示

状态栏更新

// 在UI控制器中
void UStatusUIWidgetController::BindCallbacks()
{if (AbilitySystemComponent){AbilitySystemComponent->OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, &UStatusUIWidgetController::OnEffectApplied);}
}void UStatusUIWidgetController::OnEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{// 检查效果类型并更新UIif (UGameplayEffect* GE = Spec.Def){FGameplayTagContainer AssetTags;GE->GetAssetTags(AssetTags);// 如果是增益效果if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Type.Buff"))){OnBuffApplied.Broadcast(GE, Spec.GetLevel());}// 如果是减益效果else if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Type.Debuff"))){OnDebuffApplied.Broadcast(GE, Spec.GetLevel());}// 更新状态图标UpdateStatusIcons();}
}
 

2. 音效和视觉效果系统

效果触发管理器

void UEffectResponseManager::OnGameplayEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{if (!ASC) return;AActor* TargetActor = ASC->GetAvatarActor();UGameplayEffect* GE = Spec.Def;if (!TargetActor || !GE) return;FGameplayTagContainer AssetTags;GE->GetAssetTags(AssetTags);// 根据标签播放对应效果if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Fire"))){// 播放燃烧音效和粒子UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), FireEffectParticle, TargetActor->GetActorLocation());UGameplayStatics::PlaySoundAtLocation(GetWorld(), FireEffectSound, TargetActor->GetActorLocation());}else if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Heal"))){// 播放治疗效果SpawnHealingEffect(TargetActor);}else if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Stun"))){// 播放眩晕效果ApplyStunVisuals(TargetActor);}
}
 

3. 成就和统计系统

成就追踪

void UAchievementSystem::OnEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayHandle Handle)
{// 获取施放者信息UAbilitySystemComponent* SourceASC = Spec.GetContext().GetInstigatorAbilitySystemComponent();AActor* SourceActor = SourceASC ? SourceASC->GetAvatarActor() : nullptr;// 检查是否为玩家施加的效果if (SourceActor && SourceActor->IsA(APlayerCharacter::StaticClass())){UGameplayEffect* GE = Spec.Def;FGameplayTagContainer AssetTags;GE->GetAssetTags(AssetTags);// 追踪特定类型的成就if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Damage.OverTime"))){// "施加第一个持续伤害效果"成就UnlockAchievement("FirstDoTApplied");}if (AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.CrowdControl"))){// 增加控制效果计数CrowdControlCount++;if (CrowdControlCount >= 100){UnlockAchievement("MasterOfControl");}}}
}
 

4. 战斗日志系统

战斗记录

void UCombatLogger::OnEffectApplied(UAbilitySystemComponent* TargetASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{UAbilitySystemComponent* SourceASC = Spec.GetContext().GetInstigatorAbilitySystemComponent();AActor* SourceActor = SourceASC ? SourceASC->GetAvatarActor() : nullptr;AActor* TargetActor = TargetASC->GetAvatarActor();FCombatLogEntry Entry;Entry.Timestamp = GetWorld()->GetTimeSeconds();Entry.SourceActor = SourceActor;Entry.TargetActor = TargetActor;Entry.EffectClass = Spec.Def;Entry.EffectLevel = Spec.GetLevel();// 添加到战斗日志CombatLog.Add(Entry);// 通知UI更新OnCombatLogUpdated.Broadcast(Entry);
}
 

5. 调试和开发工具

效果监控面板

void UGameplayEffectDebugger::OnEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{
#if !UE_BUILD_SHIPPING// 只在开发版本中记录FString EffectName = Spec.Def->GetName();FString TargetName = ASC->GetAvatarActor()->GetName();FString SourceName = "Unknown";if (UAbilitySystemComponent* SourceASC = Spec.GetContext().GetInstigatorAbilitySystemComponent()){SourceName = SourceASC->GetAvatarActor()->GetName();}UE_LOG(LogGameplayEffects, Log, TEXT("Effect Applied: %s from %s to %s (Level: %.1f)"),*EffectName, *SourceName, *TargetName, Spec.GetLevel());// 在调试面板显示AddToDebugHistory(EffectName, SourceName, TargetName, Spec.GetLevel());
#endif
}
 

6. 复杂的游戏机制

元素反应系统(类似原神)

void UElementalReactionSystem::OnEffectApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle)
{AActor* Target = ASC->GetAvatarActor();FGameplayTagContainer AppliedTags;Spec.Def->GetAssetTags(AppliedTags);// 检查现有的元素状态TArray<FActiveGameplayEffectHandle> ActiveEffects;ASC->GetActiveEffectsWithAllTags(ElementalTags, ActiveEffects);// 检查元素反应for (const FActiveGameplayEffectHandle& ActiveHandle : ActiveEffects){FActiveGameplayEffect* ActiveEffect = ASC->GetActiveGameplayEffect(ActiveHandle);if (ActiveEffect){FGameplayTagContainer ExistingTags;ActiveEffect->Spec.Def->GetAssetTags(ExistingTags);// 检查元素组合CheckElementalReaction(AppliedTags, ExistingTags, Target, Spec.GetContext());}}
}
 

实际项目中的最佳实践

1. 性能考虑

// 使用标签检查而不是字符串比较
bool UMySystem::ShouldProcessEffect(const FGameplayTagContainer& AssetTags)
{return AssetTags.HasTag(FGameplayTag::RequestGameplayTag("Effect.Important"));
}// 避免在频繁触发的事件中进行复杂操作
 

2. 内存管理

// 记得在销毁时解绑委托
void UMyComponent::BeginDestroy()
{if (AbilitySystemComponent){AbilitySystemComponent->OnGameplayEffectAppliedDelegateToSelf.RemoveAll(this);}Super::BeginDestroy();
}
 

这些实际应用展示了 FOnGameplayEffectAppliedDelegate 在游戏开发中的强大功能,从基础UI更新到复杂的游戏机制都能发挥重要作用。

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

相关文章:

  • 深圳深圳建设网站wordpress网盘主题
  • 北京齐力众信网站建设自己怎么制作网站
  • 想找一家公司设计网站wordpress链接设置方法
  • LeetCode 424 - 替换后的最长重复字符
  • 数据结构--9:反射、枚举以及lambda表达式(了解即可)
  • Chartjs画二氧化碳浓度曲线
  • ts语法ts语法ts语法
  • 网站打开慢原因wordpress多站点 用户同步
  • 游戏被IP限制多开,如何在同一网络下用不同IP多开游戏?
  • MiniCPM-o 2.6 小参数挑战巨头 多模态直播流直达手机
  • 网站创建免费用户可信赖的手机网站设计
  • C++20--- concept 关键字 为模板参数提供了编译期可验证的约束机制
  • 厦门市住宅建设办公室网站php开发工具 wordpress
  • 用dw做一个个人网站营销网站建设优化
  • Catia中 零件 部件 产品
  • 自动化技术演进:从工具执行到认知决策,AI如何重塑业务自动化?
  • Springboot美食私厨在线预约管理系统5zf46km2(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 网站建设公司十大id导入不了wordpress
  • php网站开发权限管理wordpress随机幻灯片
  • 团购小程序区域化运营:多门店管理、配送范围设置与本地化活动开发
  • 企业网站备案时间荆州seo优化
  • 可以做积分的网站辽宁网站建设墨子
  • c语言编译环境和运行环境 | 深入理解C语言开发环境的构成与作用
  • 做违法网站犯法吗查建设标准网站
  • Tpri-Datavue前端插件系统文档
  • jmeter发送SOAP请求对WebService接口进行测试
  • 哪个网站做任务可以赚钱网站后台的数据库怎么做
  • 自建开发工具IDE(二)文件托拽读取——东方仙盟炼气期
  • 青岛 网站科技公司wordpress商品资源
  • 数据结构 11 图