Need help with C++

I just started learning C++ and need some help.

First let me show you what I’m trying to accomplish in C++ that I did in Blueprint. I created a Blueprint Function Library in witch I have a (pure) Blueprint function that just returns an AI Controller at a given index (“Player” is the name of the Blueprint Function Library I created):

As you can see I’m casting to my game mode to access an Array of AI Controllers that is derived in the TestMode with is also a Blueprint:

This is what the “TestMode” looks like. When the game begins it is going to spawn AI players, so I created a function within TestMode called “Create AI Players”:

The function spawns AI Controllers and stores them in an array which is the array I mentioned previously.

Now I was thinking, that it would be better to recreate that function in C++, so I can use it in C++ and also in Blueprint. So I created a Blueprint Function Library in C++ and I decided to create a game state instead of game mode, but it would hold the same functionality.

This is the header of the game state I called “TEST_GameState”:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/GameState.h"
#include "GameFramework/Actor.h"
#include "AIController.h"
#include "TEST_GameState.generated.h"

/**
 * 
 */
UCLASS()
class CRASH4_API ATEST_GameState : public AGameState
{
	GENERATED_BODY()
	
public:

	ATEST_GameState(const FObjectInitializer &ObjectInitializer);

	// Declaring the number of AI players.
	UPROPERTY(BlueprintReadOnly, Category = "AI")
	TArray<AController*>AIControllers;

	// Create and spawn AI players in world.
	void TEMP_CreateAIPlayers();

	// Store all AI references in an array.
	void StoreAI();
	
	// Called when the game starts or when spawned.
	virtual void BeginPlay() override;

private:
	
	// Declare a reference to the AI controller.
	UClass* AI_CON_ref;
	AController* AI_Index_0;
	AController* AI_Index_1;
	AController* AI_Index_2;
	AController* AI_Index_3;
};

… and cpp file:

// Fill out your copyright notice in the Description page of Project Settings.

#include "Poject.h"
#include "TEST_GameState.h"
#include "bp_libs.h"

ATEST_GameState::ATEST_GameState(const FObjectInitializer &ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Get refference from AI_CON.
	static ConstructorHelpers::FObjectFinder<UBlueprint>Follower_AI_CON(TEXT("Blueprint'/Game/Blueprints/Demo/Follower_AI_Con.Follower_AI_CON'"));
	if (Follower_AI_CON.Object)
	{
		AI_CON_ref = (UClass*)Follower_AI_CON.Object->GeneratedClass;
	}

	AIControllers.SetNum(4, false);
}

// Called when the game starts or when spawned.
void ATEST_GameState::BeginPlay()
{
	Super::BeginPlay();
	TEMP_CreateAIPlayers();
	StoreAI();
}

void ATEST_GameState::TEMP_CreateAIPlayers()
{
	// Set default values.
	const FVector AI_LOC(0, 0, 0);
	const FRotator AI_ROT(0);

	// Spawn AI's in world.
	AI_Index_0 = SpawnBP<AController>(GetWorld(), AI_CON_ref, AI_LOC, AI_ROT);
	AI_Index_1 = SpawnBP<AController>(GetWorld(), AI_CON_ref, AI_LOC, AI_ROT);
	AI_Index_2 = SpawnBP<AController>(GetWorld(), AI_CON_ref, AI_LOC, AI_ROT);
	AI_Index_3 = SpawnBP<AController>(GetWorld(), AI_CON_ref, AI_LOC, AI_ROT);
}

void ATEST_GameState::StoreAI()
{
	AIControllers[0] = AI_Index_0;
	AIControllers[1] = AI_Index_1;
	AIControllers[2] = AI_Index_2;
	AIControllers[3] = AI_Index_3;
}

The Blueprint Function Library is the important part where I need help.
I called it simply Library.

Library.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "TEST_GameState.h"
#include "Library.generated.h"

/**
 * 
 */
UCLASS()
class CRASH4_API ULibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintPure, Category = "Game")
	static AController* GetAIController(int32 AI_Index);
};

Notice, I added static so in Blueprint it’ll get rid of the “Target” pin.

And for the cpp file I need help:

// Fill out your copyright notice in the Description page of Project Settings.

#include "Project.h"
#include "Library.h"
#include "TEST_GameState.h"

AController* ULibrary::GetAIController(int32 AI_Index)
{

}

How would I recreate the Blueprint Function in C++?

Hey,

I’m currently not at home, so I can only show you the way on how to accomplish what you want to do:

To get a reference to the GameState, you’d need to have a UWorld reference. You don’t have a valid world reference though, as the blueprintlibrary just doesn’t have a world context.
So you’d need to use an objectiterator (rama has a nice tutorial for it, look it up, it’s really helpful :slight_smile: ) to get a reference to the world and then get a reference to the GameState from that (MAYBE you can directly use ObjectIterator for your GameState, I don’t really know this though :frowning: ).

You’d then have to cast your GameState reference to ATEST_GameState and then you can access the AIControllers array.

I hope this was somewhat helpful. If you need specific code parts, I can help you with that, but the best practice is probably doing it yourself!

Good luck! Hope I could help! :slight_smile:

Little side note: You don’t need the AI_Index_X references if I’m not mistaken here! You could simply write directly in the array, don’t know if that was on purpose though(?)…

Hmm… You mean something like this:

   AController* ULibrary::GetAIController(int32 AI_Index)
    {
    	UWorld* World = NewObject<UWorld>();
    	ATEST_GameState* GameState = Cast<ATEST_GameState>(UGameplayStatics::GetGameState(World->GetWorld()));
    	return GameState->AIControllers[AI_Index];
    }

You need to get a reference to the “current” world, not create a new one, look at this tutorial from Rama and do the same for a UWorld object :
`A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums

Then work with that reference and retrieve its gamestate reference. :slight_smile:

Hope that helps you getting started.

OK now it works! I even actually created a GetAICharacter to get the character that the AI is controlling and also a GetPlayerHero to get the character that is controlled by a player whether if it is a human or AI.
Thank you very much.

You could do me a favor then and accept my answer! Glad that it worked :slight_smile: