文章目录

  • 使用GE为角色添加定时的Tag控制死亡时间
    • 1、添加死亡Tag
    • 2、创建死亡GE,并完成相关配置
    • 3、在AbilitySystemComponent中监听属性的变化,调用GE来添加Tag到角色上
    • 4、在角色中监听ASC传入的Tag以及Tag的层数,来响应不同的函数
  • 添加死亡、复活的逻辑
    • 1、在`CAbilitySystemComponent`中,添加回血回蓝函数
    • 2、在`CCharacter`中添加动画蒙太奇,添加一些逻辑
    • 3、到子类`CPlayerCharacter`中覆盖`OnDead`和`OnRespawn`
  • 添加布娃娃
  • 对物理资产的修改调整
    • 1、添加胶囊体
    • 2、添加约束(不然胶囊体之间会断开)


使用GE为角色添加定时的Tag控制死亡时间

1、添加死亡Tag

去Tag中添加新的标签

CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Stats_Dead)
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Stats_Dead, "Stats.Dead", "死亡")

2、创建死亡GE,并完成相关配置

添加新的GEGE_Death
在这里插入图片描述
使用拥有持续时间策略,后面幅度计算类型会采用属性基础,用等级来计算死亡时间,添加死亡标签到角色上
在这里插入图片描述

3、在AbilitySystemComponent中监听属性的变化,调用GE来添加Tag到角色上

到能力组件CAbilitySystemComponent中监听生命的变化,对生命值为0的时候添加死亡的GE

public:UCAbilitySystemComponent();// 添加GEvoid AuthApplyGameplayEffect(TSubclassOf<UGameplayEffect> GameplayEffect, int Level = 1);private:void HealthUpdated(const FOnAttributeChangeData& ChangeData);// 死亡效果UPROPERTY(EditDefaultsOnly, Category = "Gameplay Effects")TSubclassOf<UGameplayEffect> DeathEffect;
UCAbilitySystemComponent::UCAbilitySystemComponent()
{GetGameplayAttributeValueChangeDelegate(UCAttributeSet::GetHealthAttribute()).AddUObject(this, &UCAbilitySystemComponent::HealthUpdated);
}void UCAbilitySystemComponent::AuthApplyGameplayEffect(TSubclassOf<UGameplayEffect> GameplayEffect, int Level)
{if (GetOwner() && GetOwner()->HasAuthority()){FGameplayEffectSpecHandle EffectSpecHandle = MakeOutgoingSpec(GameplayEffect, Level, MakeEffectContext());ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());}
}void UCAbilitySystemComponent::HealthUpdated(const FOnAttributeChangeData& ChangeData)
{if (!GetOwner() || !GetOwner()->HasAuthority()) return;if (ChangeData.NewValue <= 0.0f){// 角色死亡if (DeathEffect){AuthApplyGameplayEffect(DeathEffect);}}
}

4、在角色中监听ASC传入的Tag以及Tag的层数,来响应不同的函数

在能力系统中使用了GE来获取Tag,然后来到角色中监听ASC获取到的Tag做出相应的响应,到CCharacter中:

#pragma region GAS组件相关
private:// 绑定GAS属性改变委托void BindGASChangeDelegates();// 死亡标签更新void DeathTagUpdated(const FGameplayTag Tag, int32 NewCount);#pragma endregion#pragma region 死亡和复活 (Death and Respawn)
private:void StartDeathSequence();void Respawn();
#pragma endregion

在角色构造函数中添加,绑定要在实现能力组件和属性初始化的下面。

ACCharacter::ACCharacter()
{PrimaryActorTick.bCanEverTick = true;// 禁用网格的碰撞功能GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);CAbilitySystemComponent = CreateDefaultSubobject<UCAbilitySystemComponent>(TEXT("CAbilitySystemComponent"));CAttributeSet = CreateDefaultSubobject<UCAttributeSet>(TEXT("CAttributeSet"));OverHeadWidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("OverHeadWidgetComponent"));OverHeadWidgetComponent->SetupAttachment(GetRootComponent());// 绑定GAS属性改变委托BindGASChangeDelegates();
}void ACCharacter::BindGASChangeDelegates()
{if (CAbilitySystemComponent){CAbilitySystemComponent->RegisterGameplayTagEvent(TGameplayTags::Stats_Dead).AddUObject(this, &ACCharacter::DeathTagUpdated);}
}void ACCharacter::DeathTagUpdated(const FGameplayTag Tag, int32 NewCount)
{// 标签数量不为0时,死亡。为0则复活。if (NewCount != 0){StartDeathSequence();}else{Respawn();}
}void ACCharacter::StartDeathSequence()
{UE_LOG(LogTemp, Warning, TEXT("%s:狗带"),*GetName())
}void ACCharacter::Respawn()
{UE_LOG(LogTemp, Warning, TEXT("%s:复活"),*GetName())
}

在角色蓝图中给角色添加死亡GE
在这里插入图片描述
在这里插入图片描述

添加死亡、复活的逻辑

1、在CAbilitySystemComponent中,添加回血回蓝函数

	// 回满血、满蓝效果void ApplyFullStatEffect();// 满血、满蓝效果UPROPERTY(EditDefaultsOnly, Category = "Gameplay Effects")TSubclassOf<UGameplayEffect> FullStatEffect;
void UCAbilitySystemComponent::ApplyFullStatEffect()
{AuthApplyGameplayEffect(FullStatEffect);
}

2、在CCharacter中添加动画蒙太奇,添加一些逻辑

#pragma region UI/*** @brief 设置头顶状态条的启用状态\n* 启用或禁用头顶UI组件的显示。\n* @param bIsEnabled 是否启用头顶UI*/void SetStatusGaugeEnabled(bool bIsEnabled);
#pragma endregion
#pragma region 死亡和复活 (Death and Respawn)
private:// 死亡蒙太奇UPROPERTY(EditDefaultsOnly, Category = "Death")TObjectPtr<UAnimMontage> DeathMontage;// 播放死亡动画void PlayDeathAnimation();// 死亡void StartDeathSequence();// 复活void Respawn();// 子类中实现virtual void OnDead();virtual void OnRespawn();
#pragma endregion
void ACCharacter::SetStatusGaugeEnabled(bool bIsEnabled)
{// 清除定时器GetWorldTimerManager().ClearTimer(HeadStatGaugeVisibilityUpdateTimerHandle);if (bIsEnabled){// 启动头顶血条ConfigureOverHeadStatusWidget();}else{// 关闭头顶血条OverHeadWidgetComponent->SetHiddenInGame(true);}
}void ACCharacter::PlayDeathAnimation()
{if (DeathMontage){PlayAnimMontage(DeathMontage);}
}void ACCharacter::StartDeathSequence()
{OnDead();// 播放死亡动画PlayDeathAnimation();// 关闭头顶血条SetStatusGaugeEnabled(false);// 禁用移动GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_None);// 禁用碰撞GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);UE_LOG(LogTemp, Warning, TEXT("%s:狗带"),*GetName())
}void ACCharacter::Respawn()
{OnRespawn();SetStatusGaugeEnabled(true);// 开启移动GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_Walking);// 开启碰撞GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);GetMesh()->GetAnimInstance()->StopAllMontages(0.f);if (CAbilitySystemComponent){CAbilitySystemComponent->ApplyFullStatEffect();}UE_LOG(LogTemp, Warning, TEXT("%s:复活"),*GetName())
}void ACCharacter::OnDead()
{
}void ACCharacter::OnRespawn()
{
}

3、到子类CPlayerCharacter中覆盖OnDeadOnRespawn

#pragma region Input// 输入开关void SetInputEnabledFromPlayerController(bool bEnabled);
#pragma endregion
#pragma region 死亡和复活 (Death and Respawn)virtual void OnDead() override;virtual void OnRespawn() override;
#pragma endregion
void ACPlayerCharacter::SetInputEnabledFromPlayerController(bool bEnabled)
{// 获取玩家控制器APlayerController* PlayerController = GetController<APlayerController>();// 如果玩家控制器为空,则返回if (!PlayerController){return;}if (bEnabled){// 启用玩家控制器输入EnableInput(PlayerController);}else{// 禁用玩家控制器输入DisableInput(PlayerController);}
}void ACPlayerCharacter::OnDead()
{// 死亡,禁用玩家控制器输入SetInputEnabledFromPlayerController(false);
}void ACPlayerCharacter::OnRespawn()
{// 复活,启用玩家控制器输入SetInputEnabledFromPlayerController(true);
}

创建一个死亡蒙太奇,设置新的插槽,关闭自动混出
在这里插入图片描述

在动画蓝图中添加这个新的插槽
在这里插入图片描述
到角色中添加死亡蒙太奇
在这里插入图片描述
添加补状态的GE,这个GE在初始化属性的时候创建了
在这里插入图片描述
打死后又会复活:
在这里插入图片描述
在这里插入图片描述

添加布娃娃

#pragma region 死亡和复活 (Death and Respawn)
private:// 相对于网格的变换FTransform MeshRelativeTransform;// 死亡蒙太奇完成时间偏移UPROPERTY(EditDefaultsOnly, Category = "Death")float DeathMontageFinishTimeShift = -0.8f;// 死亡蒙太奇UPROPERTY(EditDefaultsOnly, Category = "Death")TObjectPtr<UAnimMontage> DeathMontage;// 死亡蒙太奇计时器句柄FTimerHandle DeathMontageTimerHandle;// 死亡蒙太奇完成处理void DeathMontageFinished();// 启用/禁用 布娃娃系统void SetRagdollEnabled(bool bIsEnabled);// 播放死亡动画void PlayDeathAnimation();// 死亡void StartDeathSequence();// 复活void Respawn();virtual void OnDead();virtual void OnRespawn();
#pragma endregion
void ACCharacter::BeginPlay()
{Super::BeginPlay();ConfigureOverHeadStatusWidget();MeshRelativeTransform = GetMesh()->GetRelativeTransform();//UE_LOG(LogTemp, Warning, TEXT("ACCharacter::BeginPlay,%hhd"),GetIsReplicated());//UE_LOG(LogTemp, Warning, TEXT("True是:,%hhd"),true);
}void ACCharacter::DeathMontageFinished()
{SetRagdollEnabled(true);
}void ACCharacter::SetRagdollEnabled(bool bIsEnabled)
{if (bIsEnabled){GetMesh()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); // 从父组件分离网格,但保持世界变换不变GetMesh()->SetSimulatePhysics(true); // 启用物理模拟GetMesh()->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); // 仅启用物理碰撞}else{GetMesh()->SetSimulatePhysics(false); // 禁用物理模拟GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision); // 禁用碰撞GetMesh()->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform); // 将网格重新附加到根组件,保持相对变换GetMesh()->SetRelativeTransform(MeshRelativeTransform); // 设置网格的相对变换}
}void ACCharacter::PlayDeathAnimation()
{if (DeathMontage){// 获取死亡蒙太奇的持续时间float MontageDuration = PlayAnimMontage(DeathMontage);GetWorldTimerManager().SetTimer(DeathMontageTimerHandle, this, &ACCharacter::DeathMontageFinished, MontageDuration + DeathMontageFinishTimeShift);}
}void ACCharacter::StartDeathSequence()
{OnDead();// 播放死亡动画PlayDeathAnimation();// 关闭头顶血条SetStatusGaugeEnabled(false);// 禁用移动GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_None);// 禁用碰撞GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);UE_LOG(LogTemp, Warning, TEXT("%s:狗带"),*GetName())
}void ACCharacter::Respawn()
{OnRespawn();// 关闭布娃娃SetRagdollEnabled(false);// 开启血条SetStatusGaugeEnabled(true);// 开启移动GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_Walking);// 开启碰撞GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);// 停止所有蒙太奇GetMesh()->GetAnimInstance()->StopAllMontages(0.f);// 应用全属性if (CAbilitySystemComponent){CAbilitySystemComponent->ApplyFullStatEffect();}UE_LOG(LogTemp, Warning, TEXT("%s:复活"),*GetName())
}

用上了布娃娃系统后
在这里插入图片描述

对物理资产的修改调整

在这里插入图片描述
删除手上两个胶囊体
在这里插入图片描述
可以显示所有骨骼
在这里插入图片描述

1、添加胶囊体

在这里插入图片描述

2、添加约束(不然胶囊体之间会断开)

在这里插入图片描述
对约束增加一些限制
在这里插入图片描述
使用镜像创造对称的胶囊体(可以偷懒),对称的约束需要手动重新调制
在这里插入图片描述
给两个小腿也添加胶囊
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88460.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88460.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/88460.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jiasou TideFlow重塑AI SEO全链路自动化新标杆

引言 在Google日均处理85亿次搜索请求的数字化浪潮中&#xff0c;传统SEO工作流面临三大致命瓶颈&#xff1a;人工拓词效率低下、跨部门协作成本高企、数据监控链路断裂。因此诸如Jiasou AI SEO这样专门为AI SEO而生的Agent就应运而生了。 背景 Jiasou AIGC不仅仅可以批量生成…

CentOs 7 MySql8.0.23之前的版本主从复制

准备俩台虚拟机并启动俩台虚拟机都开启mysql后查看二进制日志是否开启先登录mysqlmysql -u root -r输入sql命令show variables like %log_bin%;如果log_bin 的value为OFF则是没有开启&#xff0c;跟着下面步骤开启二进制日志退出mysqlexitvim /etc/my.cnf在最底下添加log_binmy…

Leetcode 3607. Power Grid Maintenance

Leetcode 3607. Power Grid Maintenance 1. 解题思路2. 代码实现 题目链接&#xff1a;3607. Power Grid Maintenance 1. 解题思路 这一题思路上首先是一个DSU的思路&#xff0c;将所有的连通网络计算出来&#xff0c;并对每一个网络的节点进行归类。然后我们需要对每一个网…

开源 python 应用 开发(三)python语法介绍

最近有个项目需要做视觉自动化处理的工具&#xff0c;最后选用的软件为python&#xff0c;刚好这个机会进行系统学习。短时间学习&#xff0c;需要快速开发&#xff0c;所以记录要点步骤&#xff0c;防止忘记。 链接&#xff1a; 开源 python 应用 开发&#xff08;一&#xf…

1-Kafka介绍及常见应用场景

Kafka 介绍 Apache Kafka 是一个开源的 分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后捐赠给 Apache 软件基金会。它被设计用于高吞吐量、低延迟、可水平扩展地处理实时数据流。官网地址是&#xff1a;https://kafka.apache.org/ 以下是 Kafka 的核心介绍…

CH9121T电路及配置详解

目录1. CH9121T简介2. 原理图及接口2.1 参考电路2.2 CH9121T评估板2.3 差分端口2.4 网口灯显示2.5 晶振2.6 其他接口3. 使用手册及说明3.1 配置介绍3.2 默认参数3.3 串口波特率3.4 配置指令3.5 应用示例1. CH9121T简介 CH9121 是一款网络串口透传芯片&#xff0c;自带 10/100M…

科研数据可视化核心技术:基于 AI 与 R 语言的热图、火山图及网络图绘制实践指南

在学术研究竞争日趋激烈的背景下&#xff0c;高质量的数据可视化已成为科研成果呈现与学术传播的关键要素。据统计&#xff0c;超过 60% 的学术稿件拒稿原因与图表质量存在直接关联&#xff0c;而传统绘图工具在处理组学数据、复杂关联数据时&#xff0c;普遍存在效率低下、规范…

Windows体验macOS完整指南

一、虚拟机安装macOS专业方案1. 环境准备阶段硬件检测&#xff1a;进入BIOS&#xff08;开机时按Del/F2键&#xff09;确认开启VT-x/AMD-V虚拟化选项建议配置&#xff1a;i5十代以上CPU/16GB内存/256GB SSD软件准备&#xff1a;官网下载VMware Workstation 17 Pro获取Unlocker补…

【普及/提高−】洛谷P1577 ——切绳子

见&#xff1a;P1577 切绳子 - 洛谷 题目描述 有 N 条绳子&#xff0c;它们的长度分别为 Li​。如果从它们中切割出 K 条长度相同的绳子&#xff0c;这 K 条绳子每条最长能有多长&#xff1f;答案保留到小数点后 2 位(直接舍掉 2 位后的小数)。 输入格式 第一行两个整数 N …

imx6ull-裸机学习实验16——I2C 实验

目录 前言 I2C简介 基本特性​​ I2C 协议 起始位 停止位 数据传输 应答信号 I2C 写时序 I2C 读时序 I.MX6U I2C 简介 寄存器 地址寄存器I2Cx_IADR(x1~4) 分频寄存器I2Cx_IFDR 控制寄存器I2Cx_I2CR 状态寄存器I2Cx_I2SR 数据寄存器I2Cx_I2DR AP3216C 简介 …

【TCP/IP】5. IP 协议

5. IP 协议5. IP 协议5.1 概述5.2 IP 数据报格式5.3 无连接数据报传输5.3.1 首部校验5.3.2 数据分片与重组5.4 IP 数据报选项5.4.1 选项格式5.4.2 选项类型5.5 IP 模块的结构本章要点5. IP 协议 5.1 概述 IP 协议是 TCP/IP 协议簇的核心协议&#xff0c;位于网络层&#xff0…

Linux 服务器挖矿病毒深度处理与防护指南

在 Linux 服务器运维中&#xff0c;挖矿病毒是常见且危害较大的安全威胁。此类病毒通常会隐蔽占用大量 CPU 资源进行加密货币挖矿&#xff0c;导致服务器性能骤降、能耗激增&#xff0c;甚至被黑客远程控制。本文将从病毒特征识别、应急处理流程、深度防护措施三个维度&#xf…

MySQL数据表设计 系统的营销功能 优惠券、客户使用优惠券的设计

系统的营销功能营销功能概述&#xff1a;系统的营销功能主要是&#xff1a;市场活动管理、营销自动化、销售线索管理以及数据分析和报告等。‌ToC‌&#xff08;Consumer&#xff09;&#xff1a;面向个人消费者&#xff0c;满足日常消费需求。‌优惠券的种类&#xff1a;ToC的…

让 3 个线程串行的几种方式

1、通过join()的方式 子线程调用join()的时候&#xff0c;主线程等待子线程执行完再执行。如果让多个线程顺序执行的话&#xff0c;那么需要他们按顺序调用start()。/*** - 第一个迭代&#xff08;i0&#xff09;&#xff1a;* 启动线程t1 -> 然后调用t1.join()。* …

在 Vue 项目中关闭 ESLint 规则

在 Vue 2 项目中关闭 ESLint 规则有以下几种方法&#xff0c;根据您的需求选择合适的方式&#xff1a; 1. 完全禁用 ESLint 修改 vue.config.js&#xff08;推荐&#xff09; module.exports {// 关闭 ESLintlintOnSave: false }或修改 package.json {"scripts": {&…

电脑息屏工具,一键黑屏超方便

软件介绍 今天为大家推荐一款实用的PC端屏幕管理工具——CloseDsp。这款"息屏小能手"能一键关闭显示器&#xff0c;解决各种场景下的屏幕管理需求。 核心功能 CloseDsp最突出的特点是能瞬间关闭显示器屏幕。只需点击"关闭显示器"按钮&#xff0c;屏幕…

嵌入式调试LOG日志输出(以STM32为例)

引言在嵌入式系统开发中&#xff0c;调试是贯穿整个生命周期的关键环节。与传统PC端程序不同&#xff0c;嵌入式设备资源受限&#xff08;如内存、存储、处理器性能&#xff09;&#xff0c;且运行环境复杂&#xff08;无显示器、键盘&#xff09;&#xff0c;传统的断点调试或…

Zephyr的设备驱动模型

默认配置默认配置 boards/arm/nucleo_f401re/ ├── nucleo_f401re.dts ← 板卡设备树主入口 ├── nucleo_f401re_defconfig ← 默认 Kconfig 配置 ├── board.cmake ← CMake 构建入口overlay1.新增加驱动需要修改对应板的设备树文件&#xf…

Mysql字段没有索引,通过where x = 3 for update是使用什么级别的锁

没有索引时&#xff0c;FOR UPDATE 会锁住整个表 现在&#xff0c;你正在一本一本地翻看所有书&#xff0c;寻找“维修中”的书&#xff0c;并且你对管理员说&#xff1a;“在我清点和修改完之前&#xff0c;别人不能动这些书&#xff0c;也不能往这个范围里加新书&#xff01;…

TCP-与-UDP-协议详解:原理、区别与应用场景全解析

TCP 与 UDP 协议详解&#xff1a;原理、区别与应用场景全解析 在日常使用网络的过程中&#xff0c;我们经常听到 TCP 和 UDP 这两个词。你打开网页、发送消息、观看视频&#xff0c;背后都在使用 TCP 或 UDP 进行数据传输。那么这两个协议到底是怎么工作的&#xff1f;它们之间…