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

RPG23.应用武器伤害(一):设置武器命中

1.打开PawnCombatComponent.h

新建一个枚举

UENUM(BlueprintType)
enum class EToggleDamageType : uint8
{CurrentEquippedWeapon,LeftHand,RightHand
};

创建一个新函数

public:
//攻击时设置武器碰撞UFUNCTION(BlueprintCallable, Category = "XMB|Combat")void ToggleWeaponCollision(bool bShouldEnable, EToggleDamageType ToggleDamageType = EToggleDamageType::CurrentEquippedWeapon);
void UPawnCombatComponent::ToggleWeaponCollision(bool bShouldEnable, EToggleDamageType ToggleDamageType)
{if (ToggleDamageType == EToggleDamageType::CurrentEquippedWeapon){AWeaponBase* WeaponToToggle = GetCharacterCurrentEquippedWeapon();check(WeaponToToggle);if (bShouldEnable){WeaponToToggle->GetWeaponCollisionBox()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);Debug::Print(WeaponToToggle->GetName() + TEXT("collision enable"), FColor::Green);}else{WeaponToToggle->GetWeaponCollisionBox()->SetCollisionEnabled(ECollisionEnabled::NoCollision);Debug::Print(WeaponToToggle->GetName() + TEXT("collision disable"), FColor::Red);}}
}

3.打开项目,打开ANS_ToggleWeaponCollsiion

再去蒙太奇里将ANS调制到大约可以造成伤害的位置

4.打开weaponbase.h,添加两个函数用于碰撞结束前后

	UFUNCTION()virtual  void OnCollisionBoxBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);UFUNCTION()virtual void OnCollisionEndOverlap( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
void AWeaponBase::OnCollisionBoxBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{//APawn* WeaponOwningPawn = GetInstigator<APawn>();checkf(WeaponOwningPawn,TEXT("forgot to assign an instagtor as the owning pawn of the weapon : %s"),* GetName());if (APawn* HitPawn = Cast<APawn>(OtherActor)){if (WeaponOwningPawn != HitPawn)//命中的对象与武器装备者本身不相同{Debug::Print(FString::Printf(TEXT("begin overlap with: %s"),* HitPawn->GetName()),FColor::Green);}//TODO:Implement hit check for enemy characters}}void AWeaponBase::OnCollisionEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{//APawn* WeaponOwningPawn = GetInstigator<APawn>();checkf(WeaponOwningPawn,TEXT("forgot to assign an instagtor as the owning pawn of the weapon : %s"),* GetName());if (APawn* HitPawn = Cast<APawn>(OtherActor)){if (WeaponOwningPawn != HitPawn)//命中的对象与武器装备者本身不相同{Debug::Print(FString::Printf(TEXT("end overlap with: %s"),* HitPawn->GetName()),FColor::Red);}}
}

在构造函数内绑定这两个函数

AWeaponBase::AWeaponBase()
{PrimaryActorTick.bCanEverTick = true;WeaponMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("WeaponMesh"));SetRootComponent(WeaponMesh);WeaponCollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponCollisionBox"));WeaponCollisionBox->SetupAttachment(GetRootComponent());WeaponCollisionBox->SetBoxExtent(FVector(20.f));WeaponCollisionBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);//绑定WeaponCollisionBox->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnCollisionBoxBeginOverlap);WeaponCollisionBox->OnComponentEndOverlap.AddUniqueDynamic(this,&ThisClass::OnCollisionEndOverlap);
}

5.在weapoinbase内创建委托用于传递命中的对象

DECLARE_DELEGATE_OneParam(FOnTargetInteractedDelegate, AActor*)
public:FOnTargetInteractedDelegate OnWeaponHitTarget;FOnTargetInteractedDelegate OnWeaponPulledFromTarget;

然后在OnCollisionBoxBeginOverlap与OnCollisionEndOverlap内分别改为

void AWeaponBase::OnCollisionBoxBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{//APawn* WeaponOwningPawn = GetInstigator<APawn>();checkf(WeaponOwningPawn,TEXT("forgot to assign an instagtor as the owning pawn of the weapon : %s"),* GetName());if (APawn* HitPawn = Cast<APawn>(OtherActor)){if (WeaponOwningPawn != HitPawn)//命中的对象与武器装备者本身不相同{OnWeaponHitTarget.ExecuteIfBound(OtherActor);}//TODO:Implement hit check for enemy characters}}void AWeaponBase::OnCollisionEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{//APawn* WeaponOwningPawn = GetInstigator<APawn>();checkf(WeaponOwningPawn,TEXT("forgot to assign an instagtor as the owning pawn of the weapon : %s"),* GetName());if (APawn* HitPawn = Cast<APawn>(OtherActor)){if (WeaponOwningPawn != HitPawn)//命中的对象与武器装备者本身不相同{OnWeaponPulledFromTarget.ExecuteIfBound(OtherActor);}}
}

创建数组用于存储命中对象

protected:TArray<AActor*> OverlappedActors;

6.要在战斗组件中绑定这两个函数

首先,在PawnCombatCompnent内创建两个函数

virtual void OnHitTargetActor(AActor* HitActor);virtual void OnWeaponPulledFromTargetActor(AActor* InteractedActor);

其次,在将武器添加到映射内后,绑定这两个函数

	//简单的回调函数不需要ufunction(动态多播需要)InWeaponToRegister->OnWeaponHitTarget.BindUObject(this,&ThisClass::OnHitTargetActor);InWeaponToRegister->OnWeaponPulledFromTarget.BindUObject(this,&ThisClass::OnWeaponPulledFromTargetActor);

7.创建新标签,用于攻击时记录命中

/* Shared tags */ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Shared_Event_MeleeHit);
/* Enemy tags */UE_DEFINE_GAMEPLAY_TAG(Shared_Event_MeleeHit, "Shared.Event.MeleeHit");

8.进入XMBCombatComponent.h

对6创建的两个函数进行覆写

virtual void OnHitTargetActor(AActor* HitActor) override;virtual void OnWeaponPulledFromTargetActor(AActor* InteractedActor) override;

然后实现他们

void UXMBCombatComponent::OnHitTargetActor(AActor* HitActor)
{if (OverlappedActors.Contains(HitActor)){return;}//确保每次每个目标只收一次伤害OverlappedActors.AddUnique(HitActor);FGameplayEventData Data;Data.Instigator = GetOwningPawn();Data.Target = HitActor;UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(GetOwningPawn(),XMBGameplayTags::Shared_Event_MeleeHit,Data);
}void UXMBCombatComponent::OnWeaponPulledFromTargetActor(AActor* InteractedActor)
{}

9.启动项目,打开lightattackmaster

打开HeavyAttackMaster

10.接下来对每一个montage进行anim通知

例如这样,对每一个LightAttack或者HeavyAttack的Montage进行设置就好

测试成功

http://www.xdnf.cn/news/12960.html

相关文章:

  • AD学习(2)
  • 深入理解链接与加载:从静态库到动态库的全流程解析
  • OD 算法题 B卷【反转每对括号间的子串】
  • Java设计模式面试题详解
  • 第十二讲 | 二叉搜索树
  • 庖丁解java(一篇文章学java)
  • 风控系统中常用的概念和架构学习
  • golang循环变量捕获问题​​
  • Ⅱ.楔子 -- C♭和 cbc
  • 经典算法:排序链表
  • DQN算法(详细注释版)
  • 开源项目实战学习之YOLO11:12.7 ultralytics-models-transformer.py
  • SpringMVC简介
  • 【GPT模型训练】第一课:安装PyTorch环境
  • PandasAI使用
  • Doris-2:单虚拟机上非docker化安装Doris实验环境
  • 万利达电动机保护器接ModbusRTU转profibusDP网关与300PLC通讯
  • 2025-06-02-数据库的分类和应用
  • 大数据(3) 分布式文件系统HDFS
  • LeetCode 2894.分类求和并作差
  • 什么是函数对象
  • 【ArcGIS技巧】—村庄规划规划用地规划状态字段生成工具
  • 并发请求函数batchRequests
  • 类加载的过程
  • 【算法笔记】树套树
  • RSA和AES算法核心区别和原理解析
  • Python地理数学可视化:基于函数生成真实感地形
  • WebFuture 升级提示“不能同时包含聚集KEY和大字段””的处理办法
  • 【Docker 02】Docker 安装
  • 71常用控件_QHBoxLayout的使用