Download

Can't fill TArray of TargetPoints in the Editor!

Hi

I made a TArray of ATargetPoint



UPROPERTY(EditDefaultsOnly)
        TArray<ATargetPoint*> spawnPoints;


I have 9 TargetPoints in the level and** I want to fill the array in the editor with those target points**

3433.jpg

But when I click one of those, the array always shows “None”.

It’s like I can’t select any of them, even though they appear in that tiny window!

bump

I basically need to spawn my Actor in one of those TargetPoints (randomly chosen)

Use EditInstanceOnly instead of EditDefaultsOnly.

EditDefaultsOnly means the UPROPERTY can only be edited in the Blueprint editor and has the same initial values for all instances placed on a level. EditInstanceOnly means the opposite: it can be only edited in instances and not on the BP editor, which makes sense for properties that are meant to point to other actors in the level. EditAnywhere means the value can be edited both on the BP editor and instances.

Thanks for the answer.

Now with EditInstanceOnly it definitely works: but I don’t understand why? Why shouldn’t it work with EditDefaultsOnly?


Even though it works, I have a problem: The TargetPoints have a Location and I want my Actor to move to that location… so I simply type:



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

    // Random spawn
    int32 indexSpawn = FMath::RandRange(0, spawnPoints.Num() - 1);
    SetActorLocation(spawnPoints[indexSpawn]->GetActorLocation());
}


I’m taking a random TargetPoint from the array and applying its location to my Actor. But the Actor doesn’t move!

Has this something to do with the RootComponent which, in my case, is



    USceneComponent* scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
    RootComponent = scene;


?

EditDefaultsOnly doesn’t work because you can’t reference instances of items that are placed in a level, in a blueprint class. You can only reference items in a level in another object that exists in that level.

Also a tip - always use the ObjectInitializer version of the constructor in an actor or other UObject-derived class. I’ve always run into issues when not using it. People seem to have varying experiences with default constructors, personally I just don’t trust it.



AMyActor(const FObjectInitializer& OI);




AMyActor::AMyActor(const FObjectInitializer& OI)
: Super(OI)
{
    RootComponent = OI.CreateDefaultSubObject<USceneComponent>(this, TEXT("Scene"));
}


Thanks for the tip. But actually I already do that:



ABall::ABall(const class FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer)
{
    USceneComponent* scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
    RootComponent = scene;

    mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    mesh->bCastStaticShadow = false;
    mesh->CastShadow = false;
    mesh->bCastDynamicShadow = false;
    mesh->SetSimulatePhysics(true);

    mesh->AttachTo(RootComponent);
}


But the problem is SetActorLocation won’t spawn the Ball to the TargetLocation on BeginPlay

Not quite, you’re not using the object initializer to create the sub objects:



CreateDefaultSubobject<USceneComponent>(TEXT("Scene"))




ObjectInitializer.CreateDefaultSubObject<USceneComponent>(this, TEXT("Scene"));


Also, you need to use “SetupAttachment” in the constructor when attaching items to each other, not AttachTo. I’m willing to bet the scene component is moving, but the mesh component isn’t.

Seems to make no difference.



    USceneComponent* scene = ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("Scene"));
    RootComponent = scene;

    mesh = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Mesh"));
    mesh->bCastStaticShadow = false;
    mesh->CastShadow = false;
    mesh->bCastDynamicShadow = false;
    mesh->SetSimulatePhysics(true);

    mesh->SetupAttachment(RootComponent);


Not sure in that case, all you can do at this point is step through the code. There must be something in that array, otherwise it would be crashing.

The Array is filled.
The index mathematically results as an index between 0 and ArrayNum() - 1

The element in the array is correctly accessed and its coordinates (GetActorLocation().XYZ) can bee seen changing randomly everytime the game starts:

222.png

However, SetActorLocation does not work in BeginPlay() [code above]

**UPDATE **@TheJamsh

I tried setting the Mesh as RootComponent



RootComponent = mesh;


And it works.

The problem, though, is that now I can’t edit (scale, rotate, move) the Mesh anymore in the Blueprints!

I have read somewhere that RootComponents cannot be edited… but now I’m in trouble because the code only works if the Mesh is the Root

I’m quite confused…

To change properties of the mesh needs it needs to be a UPROPERTY with the VisibleDefaultsOnly flag.



UPROPERTY(VisibleDefaultsOnly, Category = "Components")
UStaticMeshComponent* Mesh;


Quite often you will have to re-create any blueprints that are already based on the C++ class if the constructor changes, especially when it comes to creating/removing components or changing the attachment order of things. Certain properties get serialized and it’s very hard to change them afterwards. Blueprint unfortunately gets full of junk data over time that’s hard to clear up, and a lot of these issues can be fixed by just recreating it.

You will be able to set the scale in blueprint, but you won’t be able to set the transform/rotation as the root component isn’t relative to anything as such.

The actors transform/rotation is the transform of the root component - so it makes sense that you can’t set it to something relative in the blueprint editor. If you need to set a relative transform for the mesh, then you’ll need to create a scene component at the root as you did before. If you want to expose the properties you’ll need to make another UPROPERTY for the scene component.

My gut feeling is that the blueprint needed recreating and the mesh wasn’t attached to the scene component properly.

I don’t think that’s the reason.

I’ve recreated the Blueprint and attached the mesh to the scene as you suggested (both with AttachTo and SetupAttachment) and it didn’t work the same

So is setting the mesh as Root the only possible solution?

Using a scene component as the root component should work just fine - I have no idea why it’s not working in this case.

I’m trying everything, it just doesnt’ work.

[USER=“4893”]Tim C[/USER] could this be an Engine bug or something? It’s really really strange.

Maybe the scene component is not set to moveable. Try to explicitly set that.

It is already set to be Movable… :frowning:

Sounds realy strange. Never had issues with that, realy strange other ossues though…

Maybe try a fresh project just to check…