Tarray[0] returns null when elements are inside

Hello,
So I have a Tarray for my inventory items of type APickUpItem. I have added, emplaced, inserted, and setNum() and then did the same. Basically I did everything I could think of to add items to the list. I have checked the .Num() and it returns correctly as far as I can tell. The problem occurs when I reference an item within the list like so: itemInventory[0] it always equals null.

This is how i set it up:

PlayerCharacter.h:

   UPROPERTY(EditAnywhere, BlueprintReadWrite)
    		TSubclassOf<APickUpItem> WeaponTest;

	UFUNCTION()
		void AddItemToInventory();

PlayerCharacter.cpp:

void APlayerCharacter::AddItemToInventory(){
	Inventory->inventoryItems.Add(Cast<APickUpItem>(WeaponTest));
}

void APlayerCharacter::OnToggleInventory()
{
	int32 numb = Inventory->inventoryItems.Num();
	FString strng = FString::FromInt(numb);
	if (Inventory->inventoryItems[0] == Cast<APickUpItem>(WeaponTest)){
//This returns true
		Inventory->holdInventoryItem(Inventory->inventoryItems[0]);
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Num Items In Inventory: " + strng));
	}
}

Inventory.h

void UInventory::holdInventoryItem(APickUpItem* item){
	
	if (item){
            //This returns false
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("item"));
     }
		
}

Any help would be appreciated.

Thanks,

EDIT

Okay, So using PrinfD’s suggestion i added my blueprint to the level manually by dragging and dropping it in. Blueprint is a subclass of HoldableItem which is a subclass of PickUpItem. The I then use a line trace to check what item is in view which then stored in a Actor Variable. Then of course in my player class

void APlayerCharacter::PickUp(){
    	if (canLookAtItems){
    		if (itemInView != NULL){
    			if (itemInView->IsA(APickUpItem::StaticClass())){
    				Inventory->addToInventory(Cast<APickUpItem>(itemInView));
    			}
    		}
    	}
    }

Which obviously goes to my Inventory class and does this:

    void UInventory::addToInventory(APickUpItem* item){
    	if (item != NULL){
//true
    		inventoryItems.Add(item);
    		if (inventoryItems[0] != NULL){
                    //false
    		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Add To Inventory" + inventoryItems[0]->Name.ToString()));
    		}else{
                    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Do Not Add To Inventory"));
    
    		}
    	}
    }

On another project I did something very similar… but now it does not seem to work

EDIT
Okay, So I did even more tests, the casting is not the issues, whatever is causing the object to be NULL is after or during the addition to the array.

Hey there,

could you add some more information about when these function are getting called? Do you, maybe, destroy the WeaponPickup at some point?

I add the items at the very beginning in the player constructor, and then the hold inventory items is called when I press a key.Actually I never do anything with the item because it is a test run in orDer to islate the variables. I was wond r ring that originally so I created the item so that I would know I am not adding something that isn’t there. I was wondering if It had something to do with the casting?

Are you sure that the WeaponTest is of Type APickupItem ?

Because if it’s not, the Cast will return NULL and you just add a nullptr to your Array.

if (Inventory->inventoryItems[0] == Cast(WeaponTest))

This will be true then, because if you added a nullptr to the Array and then comparing it to the Cast result (again), you have

if(nullptr == nullptr), which will be true. That’s why the IF is true, but you still have NULL for the actual item.

Make sure the WeaponTest is of Type APickupItem or at least a Children of it.

That should fix your problem (:

Cheers!

Hey,

To me it looks like your issue is with the WeaponTest variable. It’s of the type TSublcassOf (Typesafe UClass, just holds information about a class). Now you are trying to actually add this variable to the TArray, which can’t work because it’s not actually a variable of the type APickUpItem, just a reference to a subclass of APickUpItem.

So what you would want to do is use your WeaponTest variable to spawn an actor of that class in the world and then add the spawned actor to your TArray.

Hope fixes the issue.

I just tried what you suggested, and then came up with this little piece:

void UInventory::addToInventory(APickUpItem* item){
    	if (item != NULL){
    		//item->Destroy();
    		inventoryItems.Add(item);
    		if (inventoryItems[0] != NULL){
    			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Add To Inventory" + inventoryItems[0]->Name.ToString()));
    		}else{
    			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Do Not Add To Inventory"));
    
    		}
    	}
    }

Obviously says Do Not Add to Inventory on the screen. So maybe it is not a casting error.

For Some reason it wont let me put the code into proper formatting, so please, pretend it is.

I don’t notice anything wrong about this.
Did you maybe add something else to your TArray before you called this code? So that your first index could be a nullptr?
Otherwise I think you will actually need to provide some more information about how and with what values you call this function.

Did some editing to the original question, please take a look if you got the time

I don’t see any issues with the code that you provided. Do you maybe still call your void APlayerCharacter::AddItemToInventory() function anywhere? Because, as I pointed out, this will actually add a nullpointer to your TArray. And since you are only checking the first index in your addToInventory() function, that might cause the issue.

No, completely removed it. You are right though, when I insert it at 0 it works. Thanks for the help, ill have to do a lot of searching to find out where this initial element is coming from.