How to print out a warning if we reached a certain limit of UObject on screen.

Hi, I’m trying to print a warning on the screen for the number of UObjects that reached above 90%. The function that does that in unreal is called AddRange which is in the UObjectArray.cpp/h

Instead of working with NumElements + Count <= MaxElements, It seems like unreal allow us to use GUObjectArray.GetObjectArrayNum(); see doc for more info FUObjectArray | Unreal Engine Documentation

Here is what I wrote so far, not sure if im going the right direction.
Test.cpp file


#include "MaxObjectsInGameLimitWarning.h"
#include "Engine/Engine.h"


int32 UMaxObjectsInGameLimitWarning::AllObjects()
{
	/*accessing and getting the number of UBbjects in game*/
	const int32 LimitObjectWarning = GUObjectArray.GetObjectArrayNum();
	/*sanity check*/
	verify(LimitObjectWarning)

	/*looping through all of the UObjects we have*/
	for(int i = 0; i >= LimitObjectWarning; i++)
	{
		/*print to screen if the value is greater than 0.9*/
		if(LimitObjectWarning >= 0.9)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("UObject Limit has exceeded 90 percent.")));
		}
		else
		{
			return -1;
		}
	}
}

I’d appreciate any feedback at this point. Thanks in advance.

Ok sure- but I don’t think that’s a problem you’ll have to worry about for a while…
image

As for your actual code, it’s a bit off track:
Please pardon any syntax errors- I’m doing this in the forum, and late at night.

void UMaxObjectsInGameLimitWarning::PrintObjectCapacityPercent(float& ObjectCapacity)
{
    const int32 MaxObjectCount = 2162688;

	//We create a new object to see the latest count
    UObject* TempObj = NewObject<UObject>(UObject::StaticClass());
	
    //This is the latest item count
    int32 CurrentCount = TempObj->GetObjectArrayNum();

    //Scale from 0.0 to 1.0 - with the capacity being that large, this number will probably be teeny
    ObjectCapacity = CurrentCount / MaxObjectCount;

	if(ObjectCapacity >= 0.9)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("UObject Limit has exceeded 90 percent.")));
	}

    /*I don't remember what the function is to destroy an object, but it's probably not even needed here since it's not referenced outside the function*/
    TempObj->MarkGarbage();
}

Here’s more constructive comment on your original code:

int32 UMaxObjectsInGameLimitWarning::AllObjects()
{
	const int32 LimitObjectWarning = GUObjectArray.GetObjectArrayNum();
	verify(LimitObjectWarning)

	/*This is not looping through every uobject, it's just going to print 
"UObject Limit has exceeded 90 percent." for two less times than the number of UObjects- is what I was going to say. But you wrote i >= LimitObjectWarning rather than <=. There are only two cases for this- either there are 0 objects, and the program returns -1, or nothing happens. LimitObjectWarning is not a list of UObjects, it's a single int.*/
for(int i = 0; i >= LimitObjectWarning; i++)
	{
		/*Notice that this is checking an integer against a float. LimitObjectWarning is the approximate number of UObjects in the scene- a number that will never be less than 1.*/
		if(LimitObjectWarning >= 0.9)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("UObject Limit has exceeded 90 percent.")));
		}
		else
		{
			return -1;
		}
	}
}

I would strongly recommend downloading an IDE like Jetbrains Rider. It would’ve told you that the if statement was unreachable- and that might’ve pointed you towards fixing it.

Hi rokenrock, thank you for taking the time and point things in my code. Yes this makes a lot more sense now. I though, have a follow up question.

Another follow up question. The original AddRange function that adds up all UObjects is declared in UObjectArray.h

int32 AddRange(int32 Count) TSAN_SAFE
   {
   	int32 Result = NumElements + Count - 1;
   	checkf(NumElements + Count <= MaxElements, TEXT("Maximum number of   
              UObjects (%d) exceeded, make sure you update 
              MaxObjectsInGame/MaxObjectsInEditor/MaxObjectsInProgram 
              settings."), MaxElements);
   	check(Result == (NumElements + Count - 1));
   	NumElements += Count;
   	FPlatformMisc::MemoryBarrier();
   	check(Objects[Result].Object == nullptr);
   	return Result;
   }

Would inhereting from the parent class be an alternative method to get the number of used uobjects?

I don’t think it really matters if you hard-code it since it’s very unlikely to change, and it adds another dependency, but it’s probably fine if you want to.

I’m not sure what you mean by

Would inhereting from the parent class be an alternative method to get the number of used uobjects?

But after seeing that AddRange method that you were basing it off, and getting in an IDE myself, I can tell you with certainty that none of this would work.

Not only does the GetObjectArrayNum() function not exist,
image
The addrange function is referring to the max number of entries in an array. Meaning unless you store every single object inside a single array, this method will not be helping you.

Here’s a way to actually do it:

	//This gets the number of UObjects in the scene
    UFUNCTION(BlueprintCallable)
    static int32 GetObjectCount()
    {
		int32 Count = 0;
		for(TObjectIterator<UObject> It; It; ++It)
		{
			Count++;
		}
		return Count;
    }

It’s probably not the best way, but it’s simple.

1 Like

Would inhereting from the parent class be an alternative method to get the number of used uobjects?

For this I meant that I may use the AddRange function to manipulate and get the number of objects, but I can see what you mean. My main challenge is to alert the screen if we the count of the UObjects >= 90% of the total.

Well here’s the code to do that

	//This gets the number of UObjects in the scene, and prints a warning if it's close to capacity
	UFUNCTION(BlueprintCallable)
	static void PrintIfDangerousObjectCount()
	{
		float Count = 0;
		for(TObjectIterator<UObject> It; It; ++It)
		{
			Count++;
		}
		
		//Get max object count- I'll just hard code it here
		const float MaxObjectCount = 2162688;

		//If over 90%, print warning
		if (Count / MaxObjectCount > 0.9)
			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("UObject Limit has exceeded 90 percent.")));
	 }
1 Like

Yeah that’s it its similar to the original way. Its just the uobject in game vs in editor that I have to get. Thanks rokenrock.