Download

C++ Puzzle Block Question

In UE4 I am working on a Puzzle Block game in my Graphics 2 class. Our professor and our class is learning about UE4 together. Our class as a whole is a little confused about one thing in the C++ code and my professor said he would try to figure the answer out himself, but I figured I would jump start our next class with information that I find here.

Okay so in the BlockGrid.cpp file this section of code is used to create the blocks.



void AMyProject2BlockGrid::BeginPlay()
{
	Super::BeginPlay();

	// Number of blocks
	const int32 NumBlocks = Size * Size;

	// Loop to spawn each block
	for(int32 BlockIndex=0; BlockIndex<NumBlocks; BlockIndex++)
	{
		const float XOffset = (BlockIndex/Size) * BlockSpacing; // Divide by dimension
		const float YOffset = (BlockIndex%Size) * BlockSpacing; // Modulo gives remainder

		// Make postion vector, offset from Grid location
		const FVector BlockLocation = FVector(XOffset, YOffset, 0.f) + GetActorLocation();

		// Spawn a block
		AMyProject2Block* NewBlock = GetWorld()->SpawnActor<AMyProject2Block>(BlockLocation, FRotator(0,0,0));

		// Tell the block about its owner
		if(NewBlock != NULL)
		{
			NewBlock->OwningGrid = this;
		}
	}
}


The confusion starts with the following line in this function:



AMyProject2Block* NewBlock = GetWorld()->SpawnActor<AMyProject2Block>(BlockLocation, FRotator(0,0,0));


Each time it looks like it is rewriting NewBlock for each new block in the puzzle. Our problem is for the game we are creating, which is a Lights Out game, is if NewBlock is being continually being rewritten, then how is it keeping track of the addresses for the information to the blocks that are being displayed on the screen? This could be fixed by simply creating an array to store the information, but if the information is still being kept somewhere this would be inefficient. So how can we access the information for the blocks if NewBlock is being overwritten with each loop without making an array to inefficiently store the data?

THANKS!!! :slight_smile:

Well, essentially what it is doing is looping up the confusing line, and then saying, let’s spawn an actor, and then setting NewBlock variable to be the new actor, meaning that the spawned actor is independent of this variable. The NewBlock variable is a temporary variable used inside of the loop, the only thing it is actually being used for is in this area:


// Tell the block about its owner
		if(NewBlock != NULL)
		{
			NewBlock->OwningGrid = this;
		}

This is the same as saying, set the OwningGrid variable in our new actor that we spawned to be this(this actor that we are executing code in).

If you wanted to access the blocks later, you could make an array, (and no, this wouldn’t really be inefficient, it would probably only take up maybe a few kilos of RAM per block) but it really depends on when and why you’d want to access the blocks. If you’d want to loop through these blocks later and use some sort of algorithm on them, then I would suggest using the array. If you wanted to click on a block and have it do something, then the array would not be the way to go. The array is really only a good method if you know specifically which index or block in the array you are going to want to access, and generally you won’t. Hope I helped, and gave you some useful info to report back to your class with.

Edit: I did say that this spawned item is independent of the variable, but you can still do things to it using the variable. If you were to call NewBlock->Destroy(), or whatever the destroy function is, it would destroy the actor that the variable is representing, just thought I’d clear that up. I also noticed that you want an alternative to using an array, an array is really the only logical way to store references to all of them at once, but you don’t have to store their references to access them later.

You’ll likely learn about this later, but you could get a reference using a line trace (draw a line from A to B, see what items our line/pencil hits), and then using the ‘Hit Actor’, you could cast to your MyProject2Block, and then that would give you a reference. This is one of many ways to get a reference to something.