How to call a UObject method from another UObject?

None of the solutions I found to this topic seem to work.

I have a C++ class, GameManager. In it I have a method I wrote RandomizePuzzles(). I have another C++ class managing input and it has a direct reference to GameManager. I’ve setup a button to execute RandomizePuzzles(), but I get a compile error saying that the method is not a member of UObject. It seems to only have scope for UObject and is ignoring anything declared in GameManager completely. I know form my Unity experience I have to get the script component and call the method from that. I can’t figure out what the Unreal equivalence is.

// Controls.h
UCLASS()
class PORTALCHAOS_API AControls : public APawn{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Refs")
	UObject *gameManager;
private:
	void Refresh();
};

//Controls.cpp
void AControls::SetupPlayerInputComponent(class UInputComponent *InputCompoent){
    InputComponent->BindAction("Refresh", IE_Pressed, this, &AControls::Refresh);
    Super::SetupPlayerInputComponent(InputComponent);
}

void AControls::Refresh(){
	gameManager->RandomizePuzzles();
}

//GameManager.h
UCLASS()
class PORTALCHAOS_API AGameManager : public AActor{
	GENERATED_BODY()
private:
	Instruments *inst;
	Puzzle *puzzleA;
	Puzzle *puzzleB;
	Puzzle *puzzleListA[4];
	Puzzle *puzzleListB[4];

public:
	void RandomizePuzzles();
};

//GameManager.cpp
void AGameManager::RandomizePuzzles(){
	puzzleA = puzzleListA[rand() % 4];
	puzzleB = puzzleListB[rand() % 4];
	inst -> RefreshAll();
	inst -> Print();
}

I tried setting the variable to a type of UClass, same error.
I tried making it a type of GameManager with the UPROPERTY, but it says it needs to be a UClass and such.

I think that variable needs to be of GameManager. That makes the most sense to me given how little I understand Unreal’s API. But I need it to reference the current, in-scene, instance of GameManager and I have no clue how to link it without UPROPERTY().

Hey ,

Your gamemanager is declared as an UObject. Thus your Method RandomizePuzzle cannot be called because its definition is in the GameManager Class.
First change UObject* gamemanager to AGameManager* gamemanager.
Now you have to get the reference to the GameManager Class which you probably did, by setting it in the Editor.

Now you can call you function using gamemanager.

There’s still another solution.
When gamemanager is still UObject you can

if(auto CastedManager = Cast<AGameManager>(gamemanager))
{
    CastedManager->RandomizePuzzle();
}

and you problem is solved. Anyway this isn’t a good way to do this

I hope I could help you :slight_smile:

Good Luck

Greetings

I understand that a little better now, but why isn’t that a good way to do it? How else in code do I declare a variable of a class type, get an instance of that class type from the scene, and then access data in its class?

There are 2 reasons for that:

First:

Because Casting is unnecessary in this case if you definitily know that gamemanager is from Class AGameManager.

In the Details Panel you can only drag and drop or select an Actor of type AGameManager.
If you had UObject* the User could also drag and drop an AStaticMeshActor or something else which is not of type AGameManager.

With this Solution you are sure that gamemanager has to be of type AGameManager.

Second:

Casting is costlier than no checking.