Hello friends,
So, a bit of info to explain the problem I’m having - I’m making a turn-based combat prototype, and I have a few abilities that I want the units to use, so I’m using the gameplay ability system. So this is my base class for the abilities:
UCLASS()
class TURNBASEDLEARNING_API UAbilityBase : public UGameplayAbility
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
FVector TargetLocation;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
FVector TargetDirection;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class UAbilitySystemComponent* TargetGASComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
AActor* TargetActor;
};
And I’m setting the variables in the unit code, and then grant the ability to the ability system component on the unit like this:
void ACharacterUnit::UseAbilityOnTarget(int32 AbilityIndex, AUnit* TargetUnit)
{
if (AbilityIndex >= 0 && AbilityIndex < AbilitiesInBar.Num())
{
AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetLocation = TargetUnit->GetActorLocation();
AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetGASComponent = TargetUnit->GetGASComponent();
AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetActor = TargetUnit;
if (AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetActor)
{
UE_LOG(LogTemp, Warning, TEXT("Actor: %s"),
*AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetActor->GetName());
AbilityUsed = AbilitySystemComponent->GiveAbility(
FGameplayAbilitySpec(AbilitiesInBar[AbilityIndex],
1,
static_cast<int32>(AbilitiesInBar[AbilityIndex].GetDefaultObject()->AbilityInputID),
this));
AbilitySystemComponent->TryActivateAbility(AbilityUsed, false);
}
}
}
void ACharacterUnit::UseAbilityOnTarget(int32 AbilityIndex, ATile* TargetTile)
{
if (AbilityIndex >= 0 && AbilityIndex < AbilitiesInBar.Num())
{
if (AbilitiesInBar[AbilityIndex].GetDefaultObject()->AbilityRangeType == EAbilityRangeType::Movement
|| AbilitiesInBar[AbilityIndex].GetDefaultObject()->AbilityRangeType == EAbilityRangeType::MovementTeleport)
{
//UE_LOG(LogTemp, Warning, TEXT("Tile found on character: %d"), (Tile != nullptr));
Tile->ClearTile();
Tile = TargetTile;
Tile->SetUnit(this);
AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetLocation = TargetTile->GetActorLocation();
FVector Direction = TargetTile->GetActorLocation() - GetActorLocation();
Direction.Normalize();
UE_LOG(LogTemp, Warning, TEXT("Direction: %s"), *TargetTile->GetActorLocation().ToString());
if (!bIsPlayerCharacter)
{
Direction = -Direction;
}
AbilitiesInBar[AbilityIndex].GetDefaultObject()->TargetDirection = Direction;
}
AbilityUsed = AbilitySystemComponent->GiveAbility(
FGameplayAbilitySpec(AbilitiesInBar[AbilityIndex],
1,
static_cast<int32>(AbilitiesInBar[AbilityIndex].GetDefaultObject()->AbilityInputID),
this));
AbilitySystemComponent->TryActivateAbility(AbilityUsed, false);
}
}
So all is fine for the movement ability, as the character moves correctly to the tile selected. For the attack ability on the other hand, I’m having an issue, where the ability blueprint reads nullptr’s from the values of both the TargetGASComponent and TargetActor, and so fails to to apply the damage gameplay effect. Below are screenshots for the blueprints of the movement ability, which works, the attack ability, which fails, and the debug inside Visual Studio, which shows that there are values set in the TargetGASComponent and TargetActor variables of the used ability:
Thanks in advance, and best regards,
Svetlin




- for some reason I now get a crash after giving the ability system component the ability, with message: