My function is crashing my game and I don't know why

Hello, I’m working on a dice game while I am also going through a Unreal C++ course so I can use what I learn to teach myself further, so please go easy on me for any coding on unreal mistakes.

So I have a Dice Board that I am rolling the dice onto. I am attaching a C++ component to the board that will handle what numbers I have rolled. The dice themselves have box components attached labelled “1,2,3,4…” corresponding to the number on the opposite side of the die, so when the box overlaps the board, I know what number is facing up.

This is the code I have written so far for my scoring/rolling attached to my Board Actor:

my .h

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

#pragma once
#include "Engine.h"
#include "Components/ActorComponent.h"
#include "ScoringRolling.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class FARKLE_API UScoringRolling : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UScoringRolling();
	AActor* Board;

	TArray<UPrimitiveComponent*> NumbersRolled();

	TArray<UPrimitiveComponent*> OnesRolled;
	TArray<UPrimitiveComponent*> TwosRolled;
	TArray<UPrimitiveComponent*> ThreesRolled;
	TArray<UPrimitiveComponent*> FoursRolled;
	TArray<UPrimitiveComponent*> FivesRolled;
	TArray<UPrimitiveComponent*> SixessRolled;



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

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

		
	
};

Heres my .cpp:

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

#include "ScoringRolling.h"
#include "PlayerBase.h"
#define OUT

// Sets default values for this component's properties
UScoringRolling::UScoringRolling()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	// ...
	AActor* Board = GetOwner();

}




// Called when the game starts
void UScoringRolling::BeginPlay()
{
	Super::BeginPlay();

	// ...

}


// Called every frame
void UScoringRolling::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	// ...

}

TArray<UPrimitiveComponent*> UScoringRolling::NumbersRolled()
{
	//get dice rolled
	TArray<UPrimitiveComponent*>NumbersRolled;
	Board->GetOverlappingComponents(OUT NumbersRolled);

	for (const auto& Numbers : NumbersRolled)
	{
		if (Numbers->GetFName() == FName(TEXT("1")))
		{
			OnesRolled.Add(Numbers);
		}
	}


	return NumbersRolled;
}

Now what happens is, every time I put NumbersRolled() into the Tick or BeginPlay function, the game instantly crashes. I’m positive its something in my function, I’m just not sure what.
Weirdly I’m not getting any errors on compile.

Have you tried debugging it or looking at the log to see what the error is (you’ll often get the exact line where it occurred in the log).

Here’s a few things to look at:

  • In your header file you declare AActor* Board. However, in your constructor (in the cpp) you again define AActor* Board = GetOwner(). Here is should just be Board = GetOwner() as you’ve already specified it’s type as AActor* in the header file. This redeclaration is likely meaning that the actual Board variable is not getting set properly, which leads on to the next point
  • You are trying to call Board->GetOverlappingComponents(). If Board is NULL (because you’ve not set it properly (see point above)) then it can’t call GetOverlappingComponents() because Board isn’t actually anything. This kind of error is very common and you would not expect to catch it at compile time. You should consider doing a NULL check to try and catch it though (e.g. if(Board == NULL) { … do something …} or the other way around is if(Board != NULL) { … so something…)
  • Finally, I don’t think this is cause any errors but, your use of OUT in Board->GetOverlappingComponents(OUT NumbersRolled); doesn’t seem right. What does it do? I suspect you can get rid of it.

So, change your constructor to be:

UScoringRolling::UScoringRolling()
 {
     // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
     // off to improve performance if you don't need them.
     PrimaryComponentTick.bCanEverTick = true;
 
     // ...
     Board = GetOwner();
 }

And then change your Numbers rolled to have some null safety checks (in this case I’m trying to detect if it’s null and setting it. If it’s still null, don’t do anything. It’s not the most efficient but it’s a good example of the idea.

TArray<UPrimitiveComponent*> UScoringRolling::NumbersRolled()
 {
     //get dice rolled
     TArray<UPrimitiveComponent*>NumbersRolled;
     if(Board == NULL)
     {
         Board = GetOwner();
     }
     if(Board != NULL)
     {
          Board->GetOverlappingComponents(OUT NumbersRolled);
 
          for (const auto& Numbers : NumbersRolled)
          {
              if (Numbers->GetFName() == FName(TEXT("1")))
              {
                  OnesRolled.Add(Numbers);
              }
          }
     }
 
     return NumbersRolled;
 }

Awesome response, I’ll let you know how it goes as soon as I can. I use OUT just to remember that that i’m sending the info OUT of the function, definateoy not needed.

It’s working now, thank you very much Phil!!! I appreciate your lengthy response a ton, you’re doing gods work.

No problem - it always bugs me that redefining a variable doesn’t seem to create a compile time error! Good idea on defining OUT too.

Can you mark this as accepted when you get a chance. Thanks