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

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进行设置就好

测试成功

相关文章:

  • 第八章 信息安全基础知识
  • 【量化】策略交易 - 均线策略(Moving Average Strategy)
  • 智慧园区管理平台
  • SpringCloudAlibaba和SpringBoot版本问题
  • DQN强化学习怎么来使用
  • 主体与代理的义项选择用意: 融智学视域下的三元操作机制
  • Go语言中的if else控制语句
  • Python训练营---DAY48
  • AI医生时代来临!o1模型在医疗诊断中超越人类医生
  • Springboot 基于MessageSource配置国际化
  • 玄机——某次行业攻防应急响应(带镜像)
  • 力扣-131.分割回文串
  • 72常用控件_QGridLayout的使用
  • 一个自动反汇编脚本
  • 大数据(3) 分布式文件系统HDFS
  • LLMs 系列科普文(15)
  • 第13次01:广告及商品数据呈现
  • MS8312A 车规 精密、低噪、CMOS、轨到轨输入输出运算放大器,用于传感器、条形扫描器
  • 2025-06-08 思考-人被基因和社会关系双重制约
  • 打卡day48
  • 广东省建设厅安全员b证报名网站/深圳最新疫情最新消息
  • 做网站横幅的图片多大/线下推广怎么做
  • 北京天津网站建设哪家公司好/北京seo优化费用
  • 无锡做网站好/app开发公司排名
  • perl网站建设/搜索引擎优化是什么
  • 泰和网站制作/seo提升排名