RPG58.可拾取物品二:处理玩家拾取事件
1。基于PlayerGameplayABility创建其子类c++,用于处理拾取道具的ability,命名为PlayerGA_PickUpStones
protected://~ Begin UgameplayAbility Interfacevirtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;//~ End UgameplayAbility Interface
void UPlayerGA_PickUpStones::ActivateAbility(const FGameplayAbilitySpecHandle Handle,const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo,const FGameplayEventData* TriggerEventData)
{Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
}void UPlayerGA_PickUpStones::EndAbility(const FGameplayAbilitySpecHandle Handle,const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo,bool bReplicateEndAbility, bool bWasCancelled)
{Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
}
然后创建tag
ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Player_Ability_PickUp_Stones);
UE_DEFINE_GAMEPLAY_TAG(Player_Ability_PickUp_Stones, "Player.Ability.PickUp.Stones");
2。启动项目,创建一个此类的gameplay蓝图,设置tag和实例化策略
打开DAPlayerStartUAbility,
3。打开XMBStoneBase,覆写父类的函数,在重叠时尝试激活玩家拥有此标签的能力
protected:virtual void OnPickUpCollisionSphereBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;
void AXMBStoneBase::OnPickUpCollisionSphereBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{if (AWarriorPlayer* OverlapPlayerCharacter = Cast<AWarriorPlayer>(OtherActor)){OverlapPlayerCharacter->GetXMBAbilitySystemComponent()->TryActivateAbilityByTag(XMBGameplayTags::Player_Ability_PickUp_Stones);}
}
然后打开PlayerGA_PickUpStones
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "AbilitySystem/Abilities/WarriorPlayerGameplayAbility.h"
#include "Items/PickUps/XMBStoneBase.h"
#include "PlayerGA_PickUpStones.generated.h"/*** */
UCLASS()
class ARPG_GRIVITY_API UPlayerGA_PickUpStones : public UWarriorPlayerGameplayAbility
{GENERATED_BODY()protected://~ Begin UgameplayAbility Interfacevirtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;//~ End UgameplayAbility Interface//UFUNCTION(BlueprintCallable)void CollectStones();private://UPROPERTY(EditDefaultsOnly)float BoxTraceDistance = 50.f;//UPROPERTY(EditDefaultsOnly)FVector TraceBoxSize = FVector(100.f);//UPROPERTY(EditDefaultsOnly)TArray<TEnumAsByte<EObjectTypeQuery>> StoneTraceChannel;//UPROPERTY(EditDefaultsOnly)bool bDrawDebugSphere = false;//UPROPERTY()TArray<AXMBStoneBase*> CollectedStones;
};
// Fill out your copyright notice in the Description page of Project Settings.#include "AbilitySystem/Abilities/PlayerGA_PickUpStones.h"#include "Character/WarriorPlayer.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Character/WarriorPlayer.h"
#include "Items/PickUps/XMBStoneBase.h"void UPlayerGA_PickUpStones::ActivateAbility(const FGameplayAbilitySpecHandle Handle,const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo,const FGameplayEventData* TriggerEventData)
{Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
}void UPlayerGA_PickUpStones::EndAbility(const FGameplayAbilitySpecHandle Handle,const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo,bool bReplicateEndAbility, bool bWasCancelled)
{Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
}void UPlayerGA_PickUpStones::CollectStones()
{CollectedStones.Empty();AWarriorPlayer* Player = GetPlayerCharacterFromActorInfo();TArray<FHitResult> TraceHits;UKismetSystemLibrary::BoxTraceMultiForObjects(Player,Player->GetActorLocation(),Player->GetActorLocation() + -Player->GetActorUpVector() * BoxTraceDistance,TraceBoxSize / 2.f,(-Player->GetActorUpVector()).ToOrientationRotator(),StoneTraceChannel,false,TArray<AActor*>(),bDrawDebugSphere? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None,TraceHits,true);for (const FHitResult& TraceHit : TraceHits){if (AXMBStoneBase* FoundStone = Cast<AXMBStoneBase>(TraceHit.GetActor())){CollectedStones.AddUnique(FoundStone);}}if (CollectedStones.IsEmpty()){CancelAbility(GetCurrentAbilitySpecHandle(),GetCurrentActorInfo(),GetCurrentActivationInfo(),true);}
}
设置为场景动态
4。创建新标签
ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(InputTag_PickUp_Stones);
ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Player_Event_ConsumeStones);
UE_DEFINE_GAMEPLAY_TAG(InputTag_PickUp_Stones, "InputTag.PickUp.Stones");UE_DEFINE_GAMEPLAY_TAG(Player_Event_ConsumeStones, "Player.Event.ConsumeStones");
为了设置玩家在接触石头后需要进行输入才能拾取并应用效果,我们需要添加一个输入。
打开WarriorPlayer.h
void Input_PickUpStonesStarted(const FInputActionValue& InputActionValue);
void AWarriorPlayer::Input_PickUpStonesStarted(const FInputActionValue& InputActionValue)
{FGameplayEventData Data;UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(this,XMBGameplayTags::Player_Event_ConsumeStones,Data);
}
然后前往构造函数进行绑定
//WarriorInputComponent->BindAbilityInputAction(InputConfigDataAsset, this, &ThisClass::Input_AbilityInputTagPressed,&AWarriorPlayer::Input_AbilityInputTagReleased);
启动项目,打开DA_InputConfig,新建一个IA
我们需要添加一个输入
打开XMBStoneBase.h,需要先完善这个函数
//void Consume(UXMBAbilitySystemComponent* AbilitySystemComponent,int32 ApplyLevel);
protected:
//UFUNCTION(BlueprintImplementableEvent,meta = (displayname = "On Stone Consumed"))void BP_OnStoneConsumed();//UPROPERTY(EditDefaultsOnly)TSubclassOf<UGameplayEffect> StoneGameplayEffectClass;
void AXMBStoneBase::Consume(UXMBAbilitySystemComponent* AbilitySystemComponent, int32 ApplyLevel)
{check(StoneGameplayEffectClass);//获取游戏效果的默认对象CDO//调用 UClass 的模板方法,获取该类的 默认对象(CDO)。CDO 是类在加载时创建的全局单例,包含类定义的默认属性值UGameplayEffect* EffectCDO = StoneGameplayEffectClass->GetDefaultObject<UGameplayEffect>();AbilitySystemComponent->ApplyGameplayEffectToSelf(EffectCDO,ApplyLevel,AbilitySystemComponent->MakeEffectContext());BP_OnStoneConsumed();}
打开PlayerGA_PickUpStones.h,创建函数,用于在蓝图内接收事件后调用
//接收事件后调用的函数UFUNCTION(BlueprintCallable)void ConsumeStones();
void UPlayerGA_PickUpStones::ConsumeStones()
{if (CollectedStones.IsEmpty()){CancelAbility(GetCurrentAbilitySpecHandle(),GetCurrentActorInfo(),GetCurrentActivationInfo(),true);return;}for (AXMBStoneBase* CollectedStone : CollectedStones){if (CollectedStone){//在一次拾取内存多个拾取的石子应用效果CollectedStone->Consume(XMBGetAbilitySystemComponentFromActorInfo(),GetAbilityLevel());}}}
然后打开蓝图,这里是制作接收事件后角色属性的改变
这里是做玩家在捡起石头后,石头会发生声音和nia并摧毁
现在要制作两个ge,分别用来设置给healstone和ragestone。
制作一个曲线表格,用于设置ge的数值。
设置完ge后,我们需要分别进入healstone和ragestone蓝图内进行设置
至于声音方面的,需要进入到对应的音源里设置并发