Download

Struct not updating values?

Hi there. I’m not sure if this is the right section, but here goes.
I’m trying to modify some of the variables inside a struct array I made. I loop through the array with a foreach loop but it doesn’t seem to do anything, even when I hide unnecessary pins.
I thought maybe the Set Members in Struct function was not working, so I made my own functions to set members:


void AMainCharacter::SetRecharge(FCommand NCommand, const float Time)
{
	NCommand.currentRechargeTime = Time;
}

void AMainCharacter::SetTotalRecharge(FCommand NCommand, const float Time)
{
	NCommand.maxRechargeTime = Time;
}

deb936e0fb1e70155c4183d470ad55209a6c3412.jpeg

This is the struct I made:


USTRUCT(Blueprintable)
struct FCommand
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		int32 ID;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		FText CommandName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		TEnumAsByte<ECommandType> Type;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		UTexture2D* CommandIcon;

	//Base damage or recovery dealt by the command.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		int32 BaseDamage;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		TEnumAsByte<EElement> CommandElement;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		float ElementPercentage;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		float currentRechargeTime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Commands")
		float maxRechargeTime;

	FCommand()
	{
		BaseDamage = 0;
		maxRechargeTime = 1000;
		currentRechargeTime = 0;
	}
};

However, even after using those functions, the value printed on screen is still 0.2, which doesn’t make much sense. Am I doing anything wrong?

Right now you need to Break and Make the Struct. Not sure when the fix is coming, but Epic is aware of the issue.

Wow, that explains a lot. Been having this issue too but I could never understand what the problem was.

That seems to work for some reason. I expect Epic to get this solved as soon as possible.
I think this is a major issue. After all, it’s one of the most basic structures you can have…

Anyways, thanks for the help! :smiley:

As of 4.15 this is still an issue, any word on a fix for this?

It is working, what issue are you having?

@Everynone, Thank you for the fast response.

So i’m working on creating a tilegrid based game where each tile has data associated with it that I would like to store in a struct with the following properties:

Screenshot_1.png

That struct then becomes an array on which I perform loops to do mass operations on. The problem however starts when I try to store the result back into the array, I have tried nearly all fixes I could think off and found around but those “darn” (due to the profanity filter I could unfortunatly not use a more harsher term) values just refuse to be set in the array.

Screenshot_2.png

From this post I gathered that the array is not passed by reference and therefore ultimately won’t be set, see red line in the above screenshot.

Also this issue is still unresolved according to the issue tracker

Any suggestions?

EDIT: Currently trying the method proposed here by Techlord

The key when setting struct array elements is to use SetMembersInStruct, see here, especially the bottom bit:

I did try that method and got the same result at a few posts down in that thread you linked:

https://forums.unrealengine.com/showthread.php?125057-Modular-Weapon-Ammo-Storage&p=605673&viewfull=1#post605673

With the exact setup the element in the struct array never gets edited, which is the same in my case.

Works as intended in my humble opinion, see if you can replicate this:

Untitled.png

One things that is still not so great is passing struct arrays as a reference.

…It worked, but i’m just flabbergasted since I just finished recreating my system to a workaround and now it turns out that it was for nothing.

Thank you very much though!

Lessons learned: Don’t do blueprints for more than 10+ hours a day, mistakes like these start creeping in and then you waste time backtracking.

I believe that I ran into this and must have misinterpreted what the error exactly was, could you expand on this in what cases the above method might fail?

So, consider this:

structshenanigans1.PNG

So then you’re thinking, clearly looping through a struct array must be creating copies (pass by value)! Just look at them cheeky navy-blue icons:

loopdeloop.png

All right then, lets do it without the loop:

c01a9eb47e58d2d621f97dd0a52af5d843a41a0d.png

Duh, I must set it by reference, too!

956cad4b99a387e66253bcece11c7c69b99143f7.png

[HR][/HR]
You can tick pass-by-ref checkbox all day long - it’s a trap. You can’t pass struct by reference, you can’t get a pointer to a struct. As far as I know a struct is not a UOBJECT and this behaviour is not supported, not in Blueprints, that is. If I remember correctly I got it working fine in C++.

[HR][/HR]
Workarounds exist and they’re pretty straightforward, this works like a charm, for example:

16aeac921675a36c42f19187d9282e658fc31afa.png

That’s not even a workaround, tbh, that’s how things are.

Hope it helps.

uhm, it’s because your c++ code is wrong.


void AMainCharacter::SetRecharge(FCommand* NCommand, const float Time)
{
	NCommand.currentRechargeTime = Time;
}

void AMainCharacter::SetTotalRecharge(FCommand* NCommand, const float Time)
{
	NCommand.maxRechargeTime = Time;
}

Should work.
Cheers.

e/ Oh, 2015, nevermind.

I have given up on understanding this ****.
A while ago I ran head first into the problem and found no way to avoid it.
Right now I’m doing something similar and it works like a charm. I’m not even using “set member in struct”, I’m just setting array elements normally in a for-each loop.

I just hope it will continue to work.

Edit:
Actually, now that I think about it, I initially used a function parameter to access the array.
Right now I’m calling the array directly, as I’m in the messy prototyping phase. That probably circumvents the bug, even if it kinda breaks the idea of good programming.

@Everynone, THANK YOU SO MUCH!!!

I finally get it now due to your clear tutorial and have been able to re-write my grid generation with your advice and it works perfectly now.

I have ended up keeping all changes made to GeneratedMapData within the parent blueprint (might move it to gamestate) and whenever I need a value I just cast to that parent blueprint and get my GeneratedMapData values from that function result.

This is a mega necro bump, but this was the most concise result about this problem on Google. I came here because I had this problem today, on v4.20.1

I have an alternative that I thought I’d share.

Instead of using Structs, which it looks like aren’t objects and therefore can’t be passed around like objects - Use a class. In C# Unity I would do this all the time for storing data.

How to implement it in Unreal

  1. Make a new Blueprint of type Object, this becomes the data type.
  2. Add the variables you want to hold your data. I made a helper function to set both vars at once.


3. When you want to use it in another blueprint, add a variable of that type (it can be an array just fine if you want)
4. When you want to add to this array, the one thing you do have to do is Create the Object like so:

  1. What’s great is that it is really easy to get the variable data

How is this even an alternative? Sounds like apples and oranges. Helper objects are helpful, sure. But let’s say you need 100000 of these (actor will bog it down, structs will not), and then let’s save the results to a save game object… You still need structs anyway. :] Unless your project is super tiny and holds 200 variables you’re happy to save manually by hand.

If you really want to do it this way (because it’s definitely a valid if cumbersome method - I used it around 4.14 when structs were truly crashy), why not use actor/scene *components *instead? They’re much *lighter *than actors, easier to instantiate, don’t break like structs and are generally quite nifty. Consider that, or not.

Of course, it all depends on what you need it for. There have been so many changes to struts over the years and they still do not work well enough for anything serious in BP :expressionless: Shame.

I’m quite new to Unreal, so I haven’t yet gotten to attempt to save anything, it’s possible I’ll have to refactor yet again when I find that this method doesn’t work out…
When you say ‘actor will bog it down’, this Object type is simply an Object, not based off Actor so it should be fine?
How would I use a scene component instead?
Cheers!

He meant the default in-game save system in Unreal doesn’t save Object types, only primitive types that are passed as values (not references).

Since Structs in Unreal are “value types” all you need to do is re-assign the copy (result) of your modified Struct to the variable holding the “original” one once your changes to the copy are done.

I just meant that there are situations where you’re almost forced to rely on structs anyway - like the built in generic save game object system BPs are using; a system crafty folk replaces with a custom auto-save plugin…

You probably do not need to refactor anything at this point. You can start using BP structs (or not) when you’re ready to automate saving data. I was just making a point there - objects are not a replacement for structs or the other way round. Not in BP, that is.

In C++ they’re pretty close.