From Blueprint : Accessing Actor Component(C++) in another Actor Component(C++)

Hi everyone,

I am new to Unreal, with experience in C++. In this project, I am creating a weapon system that I can create multiple weapons out of a base blueprint, select different firing mechanics (e.g. pistol - one click one shot, machine gun - click and hold to shoot multiple bullets, etc).

This is how my base weapon looks like in blue print editor.

134893-weaponrange.png

This is how RangeMechanic looks like in c++.

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class PROJECT_API URangeMechanic : public UActorComponent
{
	GENERATED_BODY()

public:
	UPROPERTY( EditAnywhere, BlueprintReadWrite, meta = ( Category = "Default", OverrideNativeName = "Firing Mechanic" ) )
		TSubclassOf<UFiringMechanic> m_firingMechanic;


	// Sets default values for this component's properties
	URangeMechanic();

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

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
	UFUNCTION( BlueprintCallable, Category = "Weapon Functions" )
		virtual void UseWeapon() { UE_LOG( LogTemp, Warning, TEXT( "WII : URangeMechanic::UseWeapon" ) ); }
		
	
};

In another blueprint, I added this to allow me to trigger UseWeapon() in RangeMechanic.

As expected, when left mouse button is click during play, the following is printed

LogTemp:Warning: WII : URangeMechanic::UseWeapon

As shown above in RangeMechanic code, I have another c++ class, FiringMechanic, that is supposed to be a base class to be inherited and have it’s UseWeapon() overrided.

134895-weaponrangedetails.png

My ideal would be to have UseWeapon() in FiringMechanic, have RangeMechanic reference call that function in FiringMechanic reference. In c++, it can be done as follows.

void URangeMechanic::UseWeapon()
{
    	UFiringMechanic* fm = m_firingMechanic->GetDefaultObject<UFiringMechanic>();
    	fm->UseWeapon();
}

I prefer to have UseWeapon() in FiringMechanic and classes that inherit from it, so to do that I need to access FiringMechanic reference via RangeMechanic reference in blueprint.

So here is the question, how do I access FiringMechanic reference via RangeMechanic reference in blueprint? I can’t seem to be able to get that reference.

In blueprint the principle of calling methods on class members is the same as in C++. You can simply call m_firingMechanic->UseWeapon(). Is there any reason why you use GetDefaultObject instead of using the member direcly? maybe I’m missing some of your thoughts.

m_firingMechanic is TSubclassOf, not an instance of UFiringMechanic. Regarding how to get an instance it is in the reply below (just found out how to do it).

In the link below, ScottSpadea kindly explained differences between a user created class, UClass, and TSubclassOf.

[Understanding TSubclassOf][1]

To access FiringMechanic reference via RangeMechanic, I need to create the selected FiringMechanic as a new object.

UPROPERTY( EditAnywhere, BlueprintReadWrite, meta = ( Category = "Default", OverrideNativeName = "Firing Mechanic Class" ) )
	TSubclassOf<UFiringMechanic> m_firingMechanicClass;

m_firingMechanicClass(previously m_firingMechanic in my original post) is to be set in UE editor. Setting this does not create a reference in BeginPlay(), so I need to create an instance in BeginPlay().

  • the new variable representing FiringMechanic instance in RangeMechanic.h

    UPROPERTY( BlueprintReadWrite, meta = ( Category = “Default”, OverrideNativeName = “Firing Mechanic Instance” ) )
    UFiringMechanic* m_firingMechanic;

  • creating an instance of FiringMechanic in BeginPlay()

    // Method 1
    m_firingMechanic = m_firingMechanicClass->GetDefaultObject();
    // Method 2
    m_firingMechanic = NewObject( m_firingMechanicClass );
    Now, an instance of FiringMechanic will be available in blueprint.

TSubclassOf does not create an instance of the class selected as explained by ScottSpadea, so this instance must be created in order for it to be accessed in blueprint.