Download

How do I add an element to an array?

Hi,

I have a problem with arrays in blueprints.
Although it should seem straight forward using arrays, I somehow cant properly add an element.

It seems any reference to the array returns a mere copy, thus any element added is added to that (useless) copy, whereas the original array remains untouched.

First, I tried to get a reference to the array itself. - Doesnt work. A copy is referenced…
Then I made a “AddElement” function in the same BP where the array resides and grab the array directly from there. - Doesnt work. No data is added.

Also, if I have an array of arrays, or an array of a struct that contains an array as a member, then it seems impossible to access that embedded array either.
The for-each loop node will also offer the struct array member as a copy only.

So how do I deal with arrays in blueprints :confused:

Any help is appreciated :slight_smile:

Cheers,
Klaus

I use Array’s all the time, just an Add node does it, and nothing about using it as a copy.

Can you post a pic of your Blueprint showing the Array in it’s Variables area?

@mikepurvis

Thanks for the quick reply :slight_smile:

Sure, here is what I have:

I have a struct called “StaffUnitDef” that looks like this:

A blueprint component, called “MotherbaseBPC”, has an array variable of that struct which is prepopulated with various units.
It has functions for returning the Staff limit and other values (which works. Reading from the array is no problem).
It also has a function for adding a staff member to a specific unit.

This component is attached to a GameState object:

2d293bbc12f1cd5e46d0a0654f26898379754b78.jpeg

So far the setup.
Now I try to access/modify the array from another place. For testing purposes i chose the level blueprint.
As I try to modify the “Medical” team by adding a staff member, this is what happens on key presses:

X - a “100” is logged, correctly reading the staff limit for the medical team
C - a “0” is logged, correctly reading the initial staff size of the empty team.
M - an “added” is logged, showing that the code ran indeed.
C (again) - a “0” is logged, although the array is expected to have a new element added.

5931537ea6cc2f64cef86e20357ce62afa3b3a9b.jpeg

If you need more/better screenshots, let me know :slight_smile:

Did you set a break point in your add function and make sure the Add is called and the struct valid at that point?

It looks like it should work. But, I googled. The problem is 2D arrays are not supported in UE4 so the workarounds are a little janky.

It looks like you may need to set the inner array and can’t modify it in the outer array. So you may need to make a copy of the inner array, add your new element to it, then set that as the inner array. That is if I understood this AnswerHub post correctly.
https://answers.unrealengine.com/questions/138067/multidimensional-array-of-classes.html

Yes. I checked that that part is working.

The GetStaff GetStaffLimit and GetStaffCount functions use a similar loop and they also work.
07b43a0839c1370b82921c7025168d7de0b96a8b.jpeg

A mild understatement :slight_smile:
Especially when you have arrays with even more than 2 dimensions.
This workaround does not seem to scale very well.

I probably flatten out the data.
I just thought I could avoid the hassle that comes with linked lists :frowning:

I love working with Blueprints for Game Data, but stopped doing any complicated control structures in them entirely, so much easier in C++. You can make Blueprint Callable functions, but then modify the array’s in C++. Just make a C++ base class for your GameState and add the array’s as Properties there. You’ll want your struct’s in C++ also.

When it comes to C++ im like a one legged guy in a butt kicking contest…

If I declare my structs and enums in a separate file (to keep things organized), how would i add that to my project?
All tutorials I see just extend from AActor… Floating cones, power-ups… all interactive stuff.
I would need a good tutorial for implementing basic classes / declarations that do not spawn or exist in the level.

In the editor just click to add a C++ class. Call it Structs or something. Then put your structs and enums in it. Other C++ files just #include the header and they can use enums or structs in it. The game will have it. I have a file full of static blueprint callable functions that I also have some of my enums in, for more global type enums. If only one class is using them I put them in the header with the class.

When I do that, the created class doesnt “know” anything about UPROPERTY or USTRUCT macros… :confused:

There is nothing to know. The editor will create the file for you correctly though.

When I type in the structs in the class file that the editor gave me, this comes out when I compile.

this is the .h file:
(Sorry about the German :o it means “This declaration has no memory class or no type specifier”)

One thing. In C++, in structs everything is public by default, it’s the only difference really from a class. People by convention often use them for data only, but they can do everything a class can and are not cheaper memory wise.

But, that shouldn’t cause your compile error. I don’t see your #includes where are they? you can’t put code before them, and you need the .generated.h file that the Editor should have made for you, that is how the Engine will “know” about your file.

Here is Rama’s tutorial on structs. https://wiki.unrealengine.com/Structs,_USTRUCTS(),_They’re_Awesome

@mikepurvis

But the engine did not create these. :frowning:

I used:
-Right-click in the context browser
-Choose “New C++c class”
-Select “None” (or blank class) as parent.

The C++ files that the editor creates look then like this:

The .h file:


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

#pragma once


/**
 * 
 */
class XOF_API DataTypes
{
public:
	DataTypes();
	~DataTypes();
};

and the .cpp file:


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

#include "XOF.h"
#include "DataTypes.h"

DataTypes::DataTypes()
{
}

DataTypes::~DataTypes()
{
}

Thats all. There is no “generated” include and no includes in the .h file.

I’ve never choosen none. You need to have a parent object in the class. You don’t have to use it, or fill it with static functions.

So the best parent would be UObject then.
Since its not something that exists in the level, (does not even define a single method), anything like AActor would be overkill.
Alas, UObject cant be selected in the “New C++ class” wizzard and I have no idea how to add new class files to the project manually (so that the build tool sees them as well).

Make it anything, since you will not be instantiating it it doesn’t matter. You will put your structs above it’s declaration in the header file.

If you make a blank C++ project, one of the starter ones, can you compile it successfully and run it?

Right. It just seems, comming from the Delphi world, a bit “sloppy”. Declaring a class although you never need it.
In Object Pascal, I would simply make a unit file that declares the structs, without declaring an empty, never used, dummy class.
Cant I declare stuff in just a header file (even dropping the .cpp entirely)?

Yeah, when I chose, for example, the ThirdPerson template project, it compiles.

It’s because that generated .h file links the file so it’s available.

I’m not positive, but you can probably delete out the class it creates, just keep the #includes

There is no real overhead for having a declared but not instantiated class in C++. I’m not really familiar with Delphi or Pascal. Maybe it is the sloppy way of linking in the generated.h but it is the way I know how to do it, just let the Editor make it.

I know this is old but wanted to add my solution with blueprint only for anyone stumbling on this post (like me a while ago xD)

Getting (as a reference) the Member using the Array Index and then adding it will work !

Cheers

Actually it helped a lot, i spent all the night trying to make this work, but with this it works like a charm and it’s really simple.

Thanks a lot