-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial Attribute Mod * Refactoring of the Ability Map * Add capability to reset attribute modifiers during a SetValue call * Make the modifiers UPROPs * Add new EndTaskGMAS. Expose AbilityData to Ability BPs * Dev branch code cleanup (macOS/Linux) (#31) * Clean-up warnings, get Shipping build config working. * Further changes, to get everything compiling under macOS and Linux * Fix compile errors under clang's more stringent mode * Tag Change Delegates (#32) * Add delegates for gameplay tag change events, and matching task. * Gameplay tag binding support and animation blueprint Adds a GMAS equivalent to GAS's FGameplayTagBlueprintPropertyBindingMap, along with an animation blueprint supporting this, and an editor module to actually allow editing the binding map in question. * Swap iterator direction when removing filtered tags. * Add SetTargetDataFloat, change HasTag to HasTagExact for Grant/Active checks * Add the ability to map attributes to properties as well as tags. (#34) If a property binding has a single tag (rather than multiple), it will also be considered valid for any attribute changes which match that tag. * Boolean properties will be set as (value > 0) * Int properties will be set as the rounded attribute value. * Float and Double properties will be set as the attribute value. * Add some safety railings if you attempt to get an attribute when no attributes have been initialized. * Cleanup to property mapping. * Changes to static_cast rather than Cast in the element mapper. * Changes to allow animation blueprint to cope with reality when the ability system component is added at runtime *after* the animation blueprint is initialized. (Why would you do this.) * Clean-up active tag access. (#41) * Minor cleanup/safety checks. (#40) * Minor safety railings to debugger category. * We don't need to call our own BindInstancedStruct implementation any more. * Further improvements on anim instance, to let you set the preview class. * Additional animation utility functionality (#42) * Minor safety railings to debugger category. * We don't need to call our own BindInstancedStruct implementation any more. * Further improvements on anim instance, to let you set the preview class. * Further animation cleanup, addition of convenience GMAS_Pawn. Also cleaned up categories a bit for properties/functions. * Minor grammar change to fix clang pickiness under Linux. * Remove pass by reference on blueprint callable tag functions * Add helper functions to retrieve input action value in BP easily, add bp function library, etc. (#43) * Add helper functions to retrieve input action value in BP easily, add bp function library, etc. * update ability helpers to return gmc version of pawn and pc * Move Tag change events to check in both Aux and Sim ticks * Add check for ActionTimer before generating Effect ID. Add GetCooldownsForInputTag --------- Co-authored-by: Packetdancer <seattlesparks@mac.com> Co-authored-by: Packetdancer <rachel.c.blackman@gmail.com> Co-authored-by: Packetdancer <packetdancer@gmail.com> Co-authored-by: Peter Gilbert <33180578+petegilb@users.noreply.github.com>
- Loading branch information
1 parent
f446cd5
commit 689c7c1
Showing
37 changed files
with
1,794 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
Source/GMCAbilitySystem/Private/Ability/Tasks/SetTargetDataFloat.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include "Ability/Tasks/SetTargetDataFloat.h" | ||
|
||
#include "GMCAbilityComponent.h" | ||
|
||
|
||
UGMCAbilityTask_SetTargetDataFloat* UGMCAbilityTask_SetTargetDataFloat::SetTargetDataFloat(UGMCAbility* OwningAbility, | ||
float Float) | ||
{ | ||
UGMCAbilityTask_SetTargetDataFloat* Task = NewAbilityTask<UGMCAbilityTask_SetTargetDataFloat>(OwningAbility); | ||
Task->Ability = OwningAbility; | ||
Task->Target = Float; | ||
return Task; | ||
} | ||
|
||
void UGMCAbilityTask_SetTargetDataFloat::Activate() | ||
{ | ||
Super::Activate(); | ||
|
||
if (AbilitySystemComponent->GetNetMode() != NM_DedicatedServer) | ||
{ | ||
ClientProgressTask(); | ||
} | ||
} | ||
|
||
void UGMCAbilityTask_SetTargetDataFloat::ProgressTask(FInstancedStruct& TaskData) | ||
{ | ||
Super::ProgressTask(TaskData); | ||
const FGMCAbilityTaskTargetDataFloat Data = TaskData.Get<FGMCAbilityTaskTargetDataFloat>(); | ||
|
||
Completed.Broadcast(Data.Target); | ||
EndTask(); | ||
} | ||
|
||
void UGMCAbilityTask_SetTargetDataFloat::ClientProgressTask() | ||
{ | ||
FGMCAbilityTaskTargetDataFloat TaskData; | ||
TaskData.TaskType = EGMCAbilityTaskDataType::Progress; | ||
TaskData.AbilityID = Ability->GetAbilityID(); | ||
TaskData.TaskID = TaskID; | ||
TaskData.Target = Target; | ||
const FInstancedStruct TaskDataInstance = FInstancedStruct::Make(TaskData); | ||
|
||
Ability->OwnerAbilityComponent->QueueTaskData(TaskDataInstance); | ||
} |
2 changes: 1 addition & 1 deletion
2
Source/GMCAbilitySystem/Private/Ability/Tasks/SetTargetDataGameplayTag.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
Source/GMCAbilitySystem/Private/Ability/Tasks/WaitForGameplayTagChange.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Fill out your copyright notice in the Description page of Project Settings. | ||
|
||
|
||
#include "Ability/Tasks/WaitForGameplayTagChange.h" | ||
|
||
UGMCAbilityTask_WaitForGameplayTagChange* UGMCAbilityTask_WaitForGameplayTagChange::WaitForGameplayTagChange( | ||
UGMCAbility* OwningAbility, const FGameplayTagContainer& WatchedTags, EGMCWaitForGameplayTagChangeType ChangeType) | ||
{ | ||
UGMCAbilityTask_WaitForGameplayTagChange* Task = NewAbilityTask<UGMCAbilityTask_WaitForGameplayTagChange>(OwningAbility); | ||
Task->Tags = WatchedTags; | ||
Task->ChangeType = ChangeType; | ||
return Task; | ||
} | ||
|
||
void UGMCAbilityTask_WaitForGameplayTagChange::Activate() | ||
{ | ||
Super::Activate(); | ||
|
||
Ability->OwnerAbilityComponent->AddFilteredTagChangeDelegate(Tags, FGameplayTagFilteredMulticastDelegate::FDelegate::CreateUObject(this, &UGMCAbilityTask_WaitForGameplayTagChange::OnGameplayTagChanged)); | ||
} | ||
|
||
void UGMCAbilityTask_WaitForGameplayTagChange::OnGameplayTagChanged(const FGameplayTagContainer& AddedTags, | ||
const FGameplayTagContainer& RemovedTags) | ||
{ | ||
FGameplayTagContainer MatchedTags; | ||
|
||
switch (ChangeType) | ||
{ | ||
case Set: | ||
MatchedTags = AddedTags.Filter(Tags); | ||
break; | ||
|
||
case Unset: | ||
MatchedTags = AddedTags.Filter(Tags); | ||
break; | ||
|
||
case Changed: | ||
MatchedTags = AddedTags.Filter(Tags); | ||
MatchedTags.AppendTags(RemovedTags.Filter(Tags)); | ||
break; | ||
} | ||
|
||
if (!MatchedTags.IsEmpty()) | ||
{ | ||
Completed.Broadcast(MatchedTags); | ||
EndTask(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include "Actors/GMAS_Pawn.h" | ||
|
||
#include "EnhancedInputComponent.h" | ||
#include "EnhancedInputSubsystems.h" | ||
#include "Camera/CameraComponent.h" | ||
#include "Components/CapsuleComponent.h" | ||
#include "GameFramework/SpringArmComponent.h" | ||
#include "Utility/GMASUtilities.h" | ||
|
||
|
||
// Sets default values | ||
AGMAS_Pawn::AGMAS_Pawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) | ||
{ | ||
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. | ||
PrimaryActorTick.bCanEverTick = true; | ||
|
||
CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule")); | ||
SetRootComponent(CapsuleComponent); | ||
CapsuleComponent->SetCapsuleRadius(30.f); | ||
CapsuleComponent->SetCapsuleHalfHeight(90.f); | ||
CapsuleComponent->bEditableWhenInherited = true; | ||
CapsuleComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); | ||
CapsuleComponent->SetCollisionObjectType(ECC_Pawn); | ||
CapsuleComponent->SetCollisionResponseToAllChannels(ECR_Block); | ||
CapsuleComponent->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore); | ||
CapsuleComponent->SetCollisionResponseToChannel(ECC_Visibility, ECR_Ignore); | ||
|
||
MeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Skeletal Mesh")); | ||
MeshComponent->bEditableWhenInherited = true; | ||
MeshComponent->SetupAttachment(CapsuleComponent); | ||
MeshComponent->SetRelativeLocation(FVector(0.f, 0.f, -90.f)); | ||
MeshComponent->SetRelativeRotation(FRotator(0.f, -90.f, 0.f)); | ||
MeshComponent->SetCollisionProfileName(TEXT("NoCollision")); | ||
|
||
SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm")); | ||
SpringArmComponent->bEditableWhenInherited = true; | ||
SpringArmComponent->SetupAttachment(CapsuleComponent); | ||
SpringArmComponent->TargetArmLength = 400.f; | ||
SpringArmComponent->bUsePawnControlRotation = true; | ||
|
||
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Follow Camera")); | ||
CameraComponent->bEditableWhenInherited = true; | ||
CameraComponent->SetupAttachment(SpringArmComponent); | ||
CameraComponent->bUsePawnControlRotation = false; | ||
|
||
// Add our basic goodies. | ||
AbilitySystemComponent = CreateDefaultSubobject<UGMC_AbilitySystemComponent>(TEXT("Ability Component")); | ||
|
||
#if WITH_EDITOR | ||
UGMASUtilities::SetPropertyFlagsSafe(StaticClass(), TEXT("CapsuleComponent"), CPF_DisableEditOnInstance); | ||
UGMASUtilities::SetPropertyFlagsSafe(StaticClass(), TEXT("MeshComponent"), CPF_DisableEditOnInstance); | ||
UGMASUtilities::SetPropertyFlagsSafe(StaticClass(), TEXT("SpringArmComponent"), CPF_DisableEditOnInstance); | ||
UGMASUtilities::SetPropertyFlagsSafe(StaticClass(), TEXT("CameraComponent"), CPF_DisableEditOnInstance); | ||
UGMASUtilities::SetPropertyFlagsSafe(StaticClass(), TEXT("AbilitySystemComponent"), CPF_DisableEditOnInstance); | ||
#endif | ||
} | ||
|
||
// Called to bind functionality to input | ||
void AGMAS_Pawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) | ||
{ | ||
if (const UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent); InputMappingContext && EnhancedInput) | ||
{ | ||
if (const ULocalPlayer* Player = Cast<ULocalPlayer>(GetController())) | ||
{ | ||
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = Player->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>()) | ||
{ | ||
// Add our default system as the lowest mapping context. | ||
InputSystem->AddMappingContext(InputMappingContext, 0); | ||
} | ||
} | ||
} | ||
|
||
Super::SetupPlayerInputComponent(PlayerInputComponent); | ||
} | ||
|
107 changes: 107 additions & 0 deletions
107
Source/GMCAbilitySystem/Private/Animation/GMCAbilityAnimInstance.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#include "Animation/GMCAbilityAnimInstance.h" | ||
#include "GMCAbilityComponent.h" | ||
#include "Utility/GMASUtilities.h" | ||
|
||
UGMCAbilityAnimInstance::UGMCAbilityAnimInstance(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) | ||
{ | ||
#if WITH_EDITOR | ||
// Hide instance-only variables which we do not need cluttering everything up. | ||
UGMASUtilities::ClearPropertyFlagsSafe(StaticClass(), TEXT("GMCPawn"), CPF_SimpleDisplay | CPF_Edit); | ||
UGMASUtilities::ClearPropertyFlagsSafe(StaticClass(), TEXT("AbilitySystemComponent"), CPF_SimpleDisplay | CPF_Edit); | ||
#endif | ||
} | ||
|
||
void UGMCAbilityAnimInstance::NativeInitializeAnimation() | ||
{ | ||
Super::NativeInitializeAnimation(); | ||
|
||
bool bShouldInitializeProperties = true; | ||
|
||
// A subclass may have already set these before calling us, so check if we need to do the work. | ||
if (!AbilitySystemComponent || !GMCPawn) | ||
{ | ||
AActor* OwnerActor = GetOwningActor(); | ||
if (OwnerActor) | ||
{ | ||
GMCPawn = Cast<AGMC_Pawn>(OwnerActor); | ||
AbilitySystemComponent = Cast<UGMC_AbilitySystemComponent>(OwnerActor->GetComponentByClass(UGMC_AbilitySystemComponent::StaticClass())); | ||
} | ||
|
||
#if WITH_EDITOR | ||
if (!GetWorld()->IsGameWorld() && (!IsValid(AbilitySystemComponent) || !IsValid(GMCPawn))) | ||
{ | ||
// Create a default for in-editor preview. | ||
if (!IsValid(GMCPawn)) | ||
{ | ||
GMCPawn = EditorPreviewClass->GetDefaultObject<AGMC_Pawn>(); | ||
|
||
// Since we might have overridden the editor preview class with something that already has an ability component, | ||
// try getting the ability component again. | ||
AbilitySystemComponent = Cast<UGMC_AbilitySystemComponent>(GMCPawn->GetComponentByClass(UGMC_AbilitySystemComponent::StaticClass())); | ||
} | ||
|
||
if (!IsValid(AbilitySystemComponent)) | ||
{ | ||
// There's not going to be any attributes or tags really to work with when using the | ||
// default parent class. | ||
bShouldInitializeProperties = false; | ||
|
||
AbilitySystemComponent = NewObject<UGMC_AbilitySystemComponent>(); | ||
} | ||
} | ||
#endif | ||
} | ||
|
||
if (AbilitySystemComponent) | ||
{ | ||
#if WITH_EDITOR | ||
if (!GetWorld()->IsGameWorld()) | ||
{ | ||
// We're in the editor preview; manually instantiate our attributes for purposes of property mapping | ||
// the default values. This is a convenience for debugging in-editor, so that the editor preview's | ||
// mapped properties should match the class-level defaults for the chosen editor preview class. | ||
AbilitySystemComponent->InstantiateAttributes(); | ||
AbilitySystemComponent->SetStartingTags(); | ||
} | ||
#endif | ||
|
||
if (bShouldInitializeProperties) | ||
{ | ||
TagPropertyMap.Initialize(this, AbilitySystemComponent); | ||
} | ||
else | ||
{ | ||
UE_LOG(LogGMCAbilitySystem, Log, TEXT("%s: skipping property map initialization since we're an in-editor preview; we're using the default ability system component, and won't have valid data."), | ||
*GetClass()->GetName()); | ||
} | ||
} | ||
else | ||
{ | ||
// Don't bother with this log in editor previews. | ||
if (GetWorld()->IsGameWorld()) | ||
{ | ||
UE_LOG(LogGMCAbilitySystem, Warning, TEXT("%s: unable to find a GMC Ability System Component on %s after initializing animation blueprint. Will make a last-ditch effort in BeginPlay."), | ||
*GetClass()->GetName(), *GetOwningActor()->GetName()) | ||
} | ||
} | ||
} | ||
|
||
void UGMCAbilityAnimInstance::NativeBeginPlay() | ||
{ | ||
Super::NativeBeginPlay(); | ||
|
||
// Components added in blueprint won't be available during InitializeAnimation but will by the time we hit BeginPlay; | ||
// make a second attempt to set up our property bindings in that scenario. | ||
if (GMCPawn && !AbilitySystemComponent) | ||
{ | ||
AbilitySystemComponent = Cast<UGMC_AbilitySystemComponent>(GMCPawn->GetComponentByClass(UGMC_AbilitySystemComponent::StaticClass())); | ||
if (!AbilitySystemComponent) | ||
{ | ||
UE_LOG(LogGMCAbilitySystem, Error, TEXT("%s: last-ditch effort to find a GMC Ability System Component on %s failed!"), *GetClass()->GetPathName(), *GMCPawn->GetName()); | ||
return; | ||
} | ||
|
||
TagPropertyMap.Initialize(this, AbilitySystemComponent); | ||
} | ||
} | ||
|
Oops, something went wrong.