Avoid CAST? Alternative?

I would say, don’t do it. Because you’re starting to move the logic outside the actors again.

Why does the player need to know what kind of thing something is?

All the code to make a block work ( door, ball, etc ), lives in the block. The player doesn’t need to know.

Same with many other things.

1 Like

I mean, if you were walking down the street, and found a grid of these blocks, you could have a great time skipping about on them and they go up and down and change color, and… but you don’t know how they work.

Like that.

I personally don’t like casting unless I absolutely have to. And then I want to only cast to the parent class, if possible. There’s never cast chains to deal with.

cast to this → fail → cast to that → fail → cast to this other thing → fail →

Have to start with a structured class hierarchy.


Gameplay Tags help me avoid casting until I absolutely need to.

Parent (Item) → Child (Weapon) → Child ( AK47 )

Parent Class would default to the Item GPTag. Weapon child would be Item.Weapon… ak47 child would be Item.Weapon.AK47

That’s enough information from a trace/overlap to guide my code (flow) to do what it needs to do.

Actor → IGameplayTagAssetInterface → parse tags → do something.

I know its an item for inventory my character can pickup. I know its a weapon, so weapon data table, or switch etc. And I know exactly what specific weapon it is.

When I go to cast I’d cast on the Weapon class, because all the needed info structure is coded there. The child (ak47) would just fill in the vars, objs etc. Which 100% accessible when you cast to the immediate parent class.

Just my 2 cents.

2 Likes

Thanks for the gameplay tags, i will read it more about it.

To use the IGameplayTagAssetInterface You’ll have to create an actor in C++. Then reparent your base class with the new. Not hard.

Create a new C++ class. Name it BaseGamePlayTags. Open Visual Studio and pretty much paste in the following to the appropriate file.

BaseGamePlayTags.h

// Copyright you etc. All rights reserved.

#pragma once

#include <CoreMinimal.h>
#include <GameFramework/Actor.h>
#include <GameplayTagContainer.h>
#include <GameplayTagAssetInterface.h>
#include "ABaseGamePlayTags.generated.h"

UCLASS()
class YOURGAME_API AABaseGamePlayTags : public AActor, public IGameplayTagAssetInterface
{
    GENERATED_BODY()
    
public:    
    // Sets default values for this actor's properties
    AABaseGamePlayTags();

    // Gameplay Tag Container variable, Exposed to BP
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config GameplayTags")
        FGameplayTagContainer YourTagContainerVariable;

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Get GameplayTags
    virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override { TagContainer = YourTagContainerVariable; return; }
};

BaseGamePlayTags.cpp

// Copyright you etc. All rights reserved.


#include "Path/to/ABaseGamePlayTags.h"

// Sets default values
AABaseGamePlayTags::AABaseGamePlayTags()
{
     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AABaseGamePlayTags::BeginPlay()
{
    Super::BeginPlay();
    
}

// Called every frame
void AABaseGamePlayTags::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}
1 Like