RPG34.AI攻击
1.打开XMBABilitySystemComponent.h ,添加一个激活函数用于激活攻击
UFUNCTION(BlueprintCallable, Category = "XMB|Ability")bool TryActivateAbilityByTag(FGameplayTag AbilityTagToActivate);
bool UXMBAbilitySystemComponent::TryActivateAbilityByTag(FGameplayTag AbilityTagToActivate)
{check(AbilityTagToActivate.IsValid());//用于存储GameplayAbilitiesTArray<FGameplayAbilitySpec*> FoundABilitySpecs;//获取所有匹配标签的GameplaySpecGetActivatableGameplayAbilitySpecsByAllMatchingTags(AbilityTagToActivate.GetSingleTagContainer(),FoundABilitySpecs);if (!FoundABilitySpecs.IsEmpty()){const int32 RandomAbilityIndex = FMath::RandRange(0,FoundABilitySpecs.Num() - 1);FGameplayAbilitySpec* SpecToActivate = FoundABilitySpecs[RandomAbilityIndex];check(SpecToActivate);if (!SpecToActivate->IsActive()){return TryActivateAbility(SpecToActivate->Handle);}}return false;
}
2.打开项目,先制作一个Ability
然后创建子类
3.打开EnemyCombatComponent.h,覆写一个函数
public:virtual void OnHitTargetActor(AActor* HitActor) override ;
void UEnemyCombatComponent::OnHitTargetActor(AActor* HitActor)
{if (OverlappedActors.Contains(HitActor)){return;}OverlappedActors.AddUnique(HitActor);//TODO: Implement block checkbool bIsValidBlock = false;const bool bIsPlayerBlocking = false;const bool bIsMyAttackUnblockble = false;if (bIsPlayerBlocking && !bIsMyAttackUnblockble){//TODO:check if the block is valid}FGameplayEventData EventData;EventData.Instigator = GetOwningPawn();EventData.Target = HitActor;if (bIsValidBlock){//TODO:Handle successful block}else{UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(GetOwningPawn(),XMBGameplayTags::Shared_Event_MeleeHit,EventData);}
}
打开XMBWarriorFunctionLibrary.h
//检测是否为可攻击目标UFUNCTION(BlueprintPure, Category = "XMBWorrior|FunctionLibrary")static bool IsTargetPawnHostile(APawn* QueryPawn, APawn* TargetPawn);
bool UXMBWarriorFunctionLibrary::IsTargetPawnHostile(APawn* QueryPawn, APawn* TargetPawn)
{check(QueryPawn && TargetPawn);IGenericTeamAgentInterface* QueryTeamAgent = Cast<IGenericTeamAgentInterface>(QueryPawn->GetController());IGenericTeamAgentInterface* TargetTeamAgent = Cast<IGenericTeamAgentInterface>(TargetPawn->GetController());if (QueryTeamAgent && TargetTeamAgent){return QueryTeamAgent->GetGenericTeamId() != TargetTeamAgent->GetGenericTeamId();}return false;
}
打开XMBWeaponbase.h,为了确保player和enemy在攻击的时候不会对友军造成伤害或者在一次攻击内对对方造成多段伤害,修改OnCollisionBoxBeginOverlap与OnCollisionEndOverlap函数
void AXMBWeaponBase::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 (UXMBWarriorFunctionLibrary::IsTargetPawnHostile(WeaponOwningPawn,HitPawn))//命中的对象与武器装备者本身不相同{OnWeaponHitTarget.ExecuteIfBound(OtherActor);}}
}void AXMBWeaponBase::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 (UXMBWarriorFunctionLibrary::IsTargetPawnHostile(WeaponOwningPawn,HitPawn))//命中的对象与武器装备者本身不相同{OnWeaponPulledFromTarget.ExecuteIfBound(OtherActor);}}
}
敌人在造成伤害的时候,要通过EffectSpecHandle进行。所以在WarriorEnemyGameplayAbility内进行设置
UFUNCTION(BlueprintPure, Category = "Warrior|Ability")FGameplayEffectSpecHandle MakeEnemyDamageEffectSpecHandle(TSubclassOf<UGameplayEffect> EffectClass,const FScalableFloat& InDamageScalableFloat);
FGameplayEffectSpecHandle UWarriorEnemyGameplayAbility::MakeEnemyDamageEffectSpecHandle(TSubclassOf<UGameplayEffect> EffectClass,const FScalableFloat& InDamageScalableFloat)
{check(EffectClass);//创建HandleFGameplayEffectContextHandle ContextHandle = XMBGetAbilitySystemComponentFromActorInfo()->MakeEffectContext();ContextHandle.SetAbility(this);//设置Ability实例ContextHandle.AddSourceObject(GetAvatarActorFromActorInfo());//设置源对象ContextHandle.AddInstigator(GetAvatarActorFromActorInfo(),GetAvatarActorFromActorInfo());//在这一步指定ability的使用者和ability的拥有者FGameplayEffectSpecHandle EffectSpecHandle = XMBGetAbilitySystemComponentFromActorInfo()->MakeOutgoingSpec(EffectClass,GetAbilityLevel(),ContextHandle);EffectSpecHandle.Data->SetSetByCallerMagnitude(XMBGameplayTags::Shared_SetByCaller_BaseDamage,InDamageScalableFloat.GetValueAtLevel(GetAbilityLevel()));return EffectSpecHandle;
}
4。打开之前创建好的abiity,进行修改
然后打开CT——GuardianStates,添加一条曲线
创建两个Ability的子类
创建好蒙太奇后,添加动画状态通知