A problem in TARRAY

Hi guys, I have two issues with TArray in UE4.16. TArray is always being collected by GC, despite declaring as UPROPERTY(). Secondly, when I try to pick object up through overlap function another time the number of TArray is increased again. However, as soon as the overlap function is done the TArray will be emptied. This the code

PickItem.h

#pragma once

#include “CoreMinimal.h”
#include “GameFramework/Actor.h”
#include “Components/BoxComponent.h”
#include “PickItem.generated.h”
UCLASS()
class INVENTORY_API APickItem : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor’s properties
APickItem();

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

public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category=Storage) USceneComponent *_RootS;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Storage) UStaticMeshComponent *_MeshOfItem;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Storage) UBoxComponent _Container;
UPROPERTY(EditAnywhere)
TArray<APickItem
> _Inventory;

FRotator _Rotation;
UFUNCTION() void OnOverlapBegin( UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION() void OnOverlapEnd( UPrimitiveComponent* OverlappedComp,  AActor* OtherActor,  UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
void PrintOut();
void HideTheItem(bool CheckVisibillity);
bool bStatuteOfOverLap;

};

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

#include “PickItem.h”
#include"Components/StaticMeshComponent.h"
#include"Engine.h"
// Sets default values
APickItem::APickItem()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;
this->_RootS = CreateDefaultSubobject(TEXT(“SenceCo”));
this->_RootS = RootComponent;
this->_MeshOfItem = CreateDefaultSubobject(TEXT(“Mesh”));
this->_MeshOfItem->AttachToComponent(this->_RootS, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
this->_Container = CreateDefaultSubobject(TEXT(“Holder”));
this->_Container->SetWorldScale3D(FVector(2, 2, 2));
this->_Container->AttachToComponent(_RootS, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
this->_Container->bGenerateOverlapEvents = true;
this->_Container->OnComponentBeginOverlap.AddDynamic(this, &APickItem::OnOverlapBegin);
this->_Container->OnComponentEndOverlap.AddDynamic(this, &APickItem::OnOverlapEnd);
this->_Rotation = FRotator(0, 0, 0);
}

// Called when the game starts or when spawned
void APickItem::BeginPlay()
{
Super::BeginPlay();

}

// Called every frame
void APickItem::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
this->_MeshOfItem->AddLocalRotation(this->_Rotation*DeltaTime);
PrintOut();
}

UFUNCTION() void APickItem::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
if (OtherActor != NULL && OtherComp != NULL&& OtherActor != this)
{
this->bStatuteOfOverLap = true;
APickItem* ite = NewObject(this, FName(“ball”));

	this->_Inventory.Add(ite);
		
	GEngine->AddOnScreenDebugMessage(1, 3, FColor::Red, *(FString().FromInt(this->_Inventory.Num())));
		
	
}

}

UFUNCTION() void APickItem::OnOverlapEnd(UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
if (OtherActor != NULL && OtherComp != NULL&& OtherActor != this)
{
this->bStatuteOfOverLap = false;
int n = this->_Inventory.Num();
}
}

void APickItem::PrintOut()
{

}

void APickItem::HideTheItem(bool CheckVisibillity)
{

}

Please format your code so it will be readable…

I can just answer right away only 1 part of your question:

“when I try to pick object up through overlap function another time the number of TArray is increased again.”

Thats right! , to avoid it you should swap this line “this->_Inventory.Add(ite);” with this line “this->_Inventory.AddUnique(ite);”

Ok I see now - " APickItem ite = NewObject(this, FName(“ball”));" you are creating new item each overlap event even with AddUnique it will be a different item - unless you will overload a “==” operator for it’s class…

For now it uses a default == operator which checks for the pointer equality - which is not equal in your case since while creating a new object it will create a new object (even if it has the same properties) and thus the pointers will not be equal.

Here is something to get you started Relational Operators Overloading in C++

Thank you for replying me. I had changed to _Inventory.AddUnique(ite) before asking this, but I got the same result.Anyhow, sorry for mistyping the code

this is the code

And what do you get now with the string ?

And what is the output after you started using FString ?
Is the Array grows each time you are overlapping the same item ?

If so then you can modify your if to the following

** if (OtherActor != NULL && OtherComp != NULL&& OtherActor != this && ! bStatuteOfOverLap) **

Good Question - I think in 4.16 it had to be already fixed.
Try using an empty UPROPERTY() without anything inside the macro…

well there is a thing to try then:

It Can Work as a Work Around - but very ugly (and I would recommended to find whats wrong).

Try adding your object (not the FString) to the root.
And see if it gets cleared from the array

Because (I think that this is not a GC) GC fires once 60 secs or something like this - till then your object should still be alive for a while :).

even when i use the regular add Like _Inventory.Add(this) the result still the same as soon the as
the function end the TArray will be emptied.

still the same outcome

My question is why GC is collecting the my array each time, there is no reason to be collected

ok I am going to build the project right way

Unbelievable, is still the same result. The garbage collector collects the array

nothing changes, moreover, a problem arises when the simulation is ended,UE4 crashes
down

Then your problem is NOT the scenario when GC clears out your TArray, whether something marks this to be deleted or you have some logical error somewhere.
AddToRoot wasn’t intended to fix your problem, it was intended to check the scenario where GC clears out TArray’s values (disregarding the retain of UPROPERTY) - now it is clearly NOT the case.

so what should I try. Is problem the release of UE4.16 because I have tried all I have got from knowledge in C++

ok I will try this duck though i have feeling the problem arises from UE4 itself